Slika avtorja
Kot razvijalec programske opreme ste verjetno že slišali ta citat "Prezgodnja optimizacija je korenina vsega zla"—več kot enkrat—v vaši karieri. Medtem ko optimizacija morda ni zelo koristna (ali absolutno potrebna) za majhne projekte, je profiliranje pogosto koristno.
Ko končate s kodiranjem modula, je dobro, da svojo kodo profilirate, da izmerite, kako dolgo traja izvajanje vsakega od odsekov. To lahko pomaga prepoznati vonjave kode in usmerja optimizacije za izboljšanje kakovosti kode. Zato vedno profilirajte svojo kodo pred optimizacijo!
Če želite narediti prve korake, vam bo ta vodnik pomagal začeti s profiliranjem v Pythonu – z uporabo vgrajenega timeit in cProfil moduli. Naučili se boste uporabljati tako vmesnik ukazne vrstice kot enakovredne klicače znotraj skriptov Python.
Modul timeit je del standardne knjižnice Python in ponuja nekaj priročnih funkcij, ki jih je mogoče uporabiti za merjenje časa kratkih izrezkov kode.
Vzemimo preprost primer obračanja seznama Python. Izmerili bomo čase izvajanja pridobivanja obrnjene kopije seznama z uporabo:
- o
reversed()
funkcijo in - rezanje seznama.
>>> nums=[6,9,2,3,7]
>>> list(reversed(nums))
[7, 3, 2, 9, 6]
>>> nums[::-1]
[7, 3, 2, 9, 6]
Running timeit v ukazni vrstici
Lahko tečeš timeit
v ukazni vrstici s sintakso:
$ python -m timeit -s 'setup-code' -n 'number' -r 'repeat' 'stmt'
Izjavo morate predložiti stmt
katerih čas izvedbe je treba izmeriti.
Določite lahko setup
kodo, ko je to potrebno – z uporabo kratke možnosti -s ali dolge možnosti –setup. Nastavitvena koda se bo zagnala samo enkrat.
O number
kolikokrat zagnati stavek: kratka možnost -n ali dolga možnost –število ni obvezna. In število ponovitev tega cikla: kratka možnost -r ali dolga možnost –repeat je prav tako neobvezna.
Oglejmo si zgoraj navedeno v akciji za naš primer:
Tukaj je ustvarjanje seznama setup
koda in obračanje seznama je izjava, ki jo je treba časovno določiti:
$ python -m timeit -s 'nums=[6,9,2,3,7]' 'list(reversed(nums))'
500000 loops, best of 5: 695 nsec per loop
Ko ne določite vrednosti za repeat
, je uporabljena privzeta vrednost 5. In ko ne navedete number
, se koda zažene tolikokrat, kot je potrebno, da se doseže skupni čas vsaj 0.2 sekund.
Ta primer izrecno nastavi, kolikokrat naj se izvede stavek:
$ python -m timeit -s 'nums=[6,9,2,3,7]' -n 100Bu000 'list(reversed(nums))'
100000 loops, best of 5: 540 nsec per loop
Privzeta vrednost za repeat
je 5, vendar ga lahko nastavimo na poljubno primerno vrednost:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' -r 3 'list(reversed(nums))'
500000 loops, best of 3: 663 nsec per loop
Oglejmo si tudi čas pristopa rezanja seznama:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' 'nums[::-1]'
1000000 loops, best of 5: 142 nsec per loop
Zdi se, da je pristop rezanja seznama hitrejši (vsi primeri so v Pythonu 3.10 na Ubuntu 22.04).
Čas izvajanja v skriptu Python
Tukaj je enakovreden času izvajanja znotraj skripta Python:
import timeit setup = 'nums=[9,2,3,7,6]'
number = 100000
stmt1 = 'list(reversed(nums))'
stmt2 = 'nums[::-1]' t1 = timeit.timeit(setup=setup,stmt=stmt1,number=number)
t2 = timeit.timeit(setup=setup,stmt=stmt2,number=number) print(f"Using reversed() fn.: {t1}")
print(f"Using list slicing: {t2}")
O timeit()
callable vrne čas izvajanja stmt
za number
večkrat. Upoštevajte, da lahko izrecno omenimo, kolikokrat je treba zagnati ali narediti number
vzemite privzeto vrednost 1000000.
Output >>
Using reversed() fn.: 0.08982690000000002
Using list slicing: 0.015550800000000004
To zažene stavek – brez ponavljanja funkcije časovnika – za podano number
krat in vrne čas izvedbe. Prav tako je precej pogosta uporaba time.repeat()
in si vzemite minimalni čas, kot je prikazano:
import timeit setup = 'nums=[9,2,3,7,6]'
number = 100000
stmt1 = 'list(reversed(nums))'
stmt2 = 'nums[::-1]' t1 = min(timeit.repeat(setup=setup,stmt=stmt1,number=number))
t2 = min(timeit.repeat(setup=setup,stmt=stmt2,number=number)) print(f"Using reversed() fn.: {t1}")
print(f"Using list slicing: {t2}")
To bo ponovilo postopek izvajanja kode number
krat repeat
število krat in vrne najmanjši čas izvajanja. Tu imamo 5 ponovitev po 100000-krat.
Output >>
Using reversed() fn.: 0.055375300000000016
Using list slicing: 0.015101400000000043
Videli smo, kako se lahko timeit uporablja za merjenje časov izvajanja kratkih odrezkov kode. Vendar je v praksi bolj koristno profilirati celoten skript Python.
To nam bo dalo čas izvajanja vseh funkcij in klicev metod – vključno z vgrajenimi funkcijami in metodami. Tako lahko dobimo boljšo predstavo o dražjih funkcijskih klicih in prepoznamo priložnosti za optimizacijo. Na primer: morda je klic API-ja prepočasen. Lahko pa ima funkcija zanko, ki jo je mogoče nadomestiti z bolj Pythonic izrazom razumevanja.
Naučimo se profilirati skripte Python z uporabo modula cProfile (prav tako del standardne knjižnice Python).
Razmislite o naslednjem skriptu Python:
# main.py
import time def func(num): for i in range(num): print(i) def another_func(num): time.sleep(num) print(f"Slept for {num} seconds") def useful_func(nums, target): if target in nums: return nums.index(target) if __name__ == "__main__": func(1000) another_func(20) useful_func([2, 8, 12, 4], 12)
Tukaj imamo tri funkcije:
func()
ki preleti niz števil in jih natisne.another func()
ki vsebuje klic nasleep()
Funkcija.useful_func()
ki vrne indeks ciljne številke na seznamu (če je cilj na seznamu).
Zgoraj navedene funkcije bodo poklicane vsakič, ko zaženete skript main.py.
Zagon cProfile v ukazni vrstici
Zaženite cProfile v ukazni vrstici z:
python3 -m file-name.py
Tu smo datoteko poimenovali main.py:
python3 -m main.py
Zagon tega bi vam moral dati naslednje rezultate:
Output >> 0 ... 999 Slept for 20 seconds
In naslednji profil:
Tu ncalls
se nanaša na število klicev funkcije in percall
se nanaša na čas na klic funkcije. Če je vrednost ncalls
je torej večji od ena percall
je povprečni čas vseh klicev.
Prevladuje čas izvajanja skripta another_func
ki uporablja vgrajeno sleep
klic funkcije (spi 20 sekund). To vidimo print
tudi funkcijski klici so precej dragi.
Uporaba cProfile v skriptu Python
Čeprav zagon cProfile v ukazni vrstici deluje dobro, lahko skriptu Python dodate tudi funkcijo profiliranja. Uporabite lahko cProfile skupaj z modul pstats za profiliranje in dostop do statistike.
Kot najboljšo prakso za boljše upravljanje nastavitve in razgradnje virov uporabite stavek with in ustvarite objekt profila, ki se uporablja kot upravitelj konteksta:
# main.py
import pstats
import time
import cProfile def func(num): for i in range(num): print(i) def another_func(num): time.sleep(num) print(f"Slept for {num} seconds") def useful_func(nums, target): if target in nums: return nums.index(target) if __name__ == "__main__": with cProfile.Profile() as profile: func(1000) another_func(20) useful_func([2, 8, 12, 4], 12) profile_result = pstats.Stats(profile) profile_result.print_stats()
Oglejmo si podrobneje ustvarjeni izhodni profil:
Ko profilirate velik skript, vam bo v pomoč razvrstite rezultate po času izvajanja. Če želite to narediti, lahko pokličete sort_stats
na objektu profila in razvrsti glede na čas izvajanja:
...
if __name__ == "__main__": with cProfile.Profile() as profile: func(1000) another_func(20) useful_func([2, 8, 12, 4], 12) profile_result = pstats.Stats(profile) profile_result.sort_stats(pstats.SortKey.TIME) profile_result.print_stats()
Ko zdaj zaženete skript, bi morali imeti možnost videti rezultate, razvrščene po času:
Upam, da vam bo ta vodnik pomagal začeti s profiliranjem v Pythonu. Vedno si zapomnite, da optimizacije nikoli ne smejo priti na ceno berljivosti. Če vas zanima več o drugih profilerjih, vključno s paketi Python tretjih oseb, si oglejte to članek o Python profilerjih.
Bala Priya C je razvijalec in tehnični pisec iz Indije. Rada dela na presečišču matematike, programiranja, znanosti o podatkih in ustvarjanja vsebin. Njena področja zanimanja in strokovnega znanja vključujejo DevOps, znanost o podatkih in obdelavo naravnega jezika. Uživa v branju, pisanju, kodiranju in kavi! Trenutno se uči in svoje znanje deli s skupnostjo razvijalcev, tako da piše vadnice, vodnike z navodili, mnenja in drugo.
- Distribucija vsebine in PR s pomočjo SEO. Okrepite se še danes.
- PlatoData.Network Vertical Generative Ai. Opolnomočite se. Dostopite tukaj.
- PlatoAiStream. Web3 Intelligence. Razširjeno znanje. Dostopite tukaj.
- PlatoESG. Avtomobili/EV, Ogljik, CleanTech, Energija, Okolje, sončna energija, Ravnanje z odpadki. Dostopite tukaj.
- PlatoHealth. Obveščanje o biotehnologiji in kliničnih preskušanjih. Dostopite tukaj.
- ChartPrime. Izboljšajte svojo igro trgovanja s ChartPrime. Dostopite tukaj.
- BlockOffsets. Posodobitev okoljskega offset lastništva. Dostopite tukaj.
- vir: https://www.kdnuggets.com/profiling-python-code-using-timeit-and-cprofile?utm_source=rss&utm_medium=rss&utm_campaign=profiling-python-code-using-timeit-and-cprofile
- : je
- :ne
- 10
- 100000
- 12
- 13
- 15%
- 17
- 19
- 20
- 22
- 7
- 8
- 9
- a
- Sposobna
- O meni
- nad
- absolutno
- Dostop
- ACM
- čez
- Ukrep
- dodajte
- vsi
- Prav tako
- vedno
- an
- in
- kaj
- API
- pristop
- SE
- območja
- AS
- At
- avtorstvo
- povprečno
- temeljijo
- BE
- pred
- BEST
- Boljše
- tako
- vgrajeno
- vendar
- by
- klic
- se imenuje
- poziva
- CAN
- Lahko dobiš
- Kariera
- CFM
- preveriti
- bližje
- Koda
- Kodiranje
- kako
- Skupno
- skupnost
- Vsebuje
- vsebina
- ustvarjanje vsebine
- ozadje
- udobje
- strošek
- skupaj
- ustvarjajo
- Ustvarjanje
- Oblikovanje
- Trenutno
- cikel
- datum
- znanost o podatkih
- privzeto
- Razvojni
- DevOps
- do
- dont
- vsak
- Celotna
- Enakovredna
- Primer
- Primeri
- izvršiti
- izvedba
- drago
- strokovno znanje
- izraz
- hitreje
- Nekaj
- file
- konec
- prva
- prvi koraki
- po
- za
- iz
- funkcija
- funkcionalnost
- funkcije
- ustvarila
- dobili
- Daj
- dobro
- več
- vodi
- Vodniki
- ročaj
- Imajo
- Slišal
- pomoč
- pomoč
- Pomaga
- jo
- tukaj
- upam,
- Kako
- Kako
- Vendar
- HTML
- HTTPS
- i
- Ideja
- identificirati
- if
- uvoz
- izboljšanje
- in
- vključujejo
- Vključno
- Indeks
- india
- v notranjosti
- obresti
- zainteresirani
- vmesnik
- križišče
- IT
- KDnuggets
- znanje
- jezik
- velika
- UČITE
- učenje
- vsaj
- Knjižnica
- Verjeten
- všeč mi je
- vrstica
- Seznam
- Long
- Poglej
- Glavne
- Znamka
- upravitelj
- več
- math
- Maj ..
- merjenje
- izmerjena
- omenjam
- Metoda
- Metode
- morda
- minimalna
- modul
- Moduli
- več
- Imenovan
- naravna
- Naravni jezik
- Obdelava Natural Language
- potrebno
- potrebna
- nikoli
- Opaziti..
- zdaj
- Številka
- številke
- predmet
- pridobitev
- of
- Ponudbe
- pogosto
- on
- enkrat
- ONE
- samo
- Mnenje
- Priložnosti
- optimizacija
- Možnost
- or
- Ostalo
- naši
- ven
- izhod
- pakete
- del
- za
- kosov
- platon
- Platonova podatkovna inteligenca
- PlatoData
- praksa
- predstaviti
- printi
- Postopek
- obravnavati
- profil
- profiliranje
- Programiranje
- projekti
- zagotavljajo
- Python
- kakovost
- kvota
- območje
- dosežejo
- reading
- nanaša
- ne pozabite
- ponovite
- nadomesti
- obvezna
- vir
- Rezultati
- vrnitev
- vrne
- koren
- Run
- tek
- deluje
- s
- Znanost
- script
- skripte
- sekund
- oddelki
- glej
- Zdi se,
- videl
- nastavite
- Kompleti
- nastavitev
- delitev
- je
- Kratke Hlače
- shouldnt
- pokazale
- Enostavno
- počasi
- majhna
- So
- Software
- določeno
- standardna
- začel
- Izjava
- Statistika
- Koraki
- primerna
- Super
- sintaksa
- T1
- Bodite
- meni
- ciljna
- teardown
- tehnični
- kot
- da
- O
- Njih
- POTEM
- Tukaj.
- tretjih oseb
- ta
- 3
- skozi
- čas
- Časovno
- krat
- do
- tudi
- Skupaj za plačilo
- vaje
- Ubuntu
- us
- uporaba
- Rabljeni
- uporablja
- uporabo
- vrednost
- Vrednote
- we
- kdaj
- medtem
- katerih
- bo
- z
- deluje
- deluje
- Pisatelj
- pisanje
- jo
- Vaša rutina za
- zefirnet