Bilde av forfatter
Som programvareutvikler har du sannsynligvis hørt sitatet "For tidlig optimalisering er roten til alt ondt"–mer enn én gang – i karrieren din. Selv om optimalisering kanskje ikke er veldig nyttig (eller absolutt nødvendig) for små prosjekter, er profilering ofte nyttig.
Etter at du er ferdig med å kode en modul, er det en god praksis å profilere koden din for å måle hvor lang tid hver av seksjonene tar å utføre. Dette kan hjelpe med å identifisere kodelukter og veilede optimaliseringer for å forbedre kodekvaliteten. Så profiler alltid koden din før du optimaliserer!
For å ta de første trinnene, vil denne veiledningen hjelpe deg å komme i gang med profilering i Python – ved å bruke den innebygde tid og cProfil moduler. Du vil lære å bruke både kommandolinjegrensesnittet og tilsvarende callables i Python-skript.
Timeit-modulen er en del av Python-standardbiblioteket og tilbyr noen få praktiske funksjoner som kan brukes til å time korte kodebiter.
La oss ta et enkelt eksempel på å snu en Python-liste. Vi måler utførelsestidene for å få en reversert kopi av listen ved å bruke:
- de
reversed()
funksjon, og - listeskjæring.
>>> nums=[6,9,2,3,7]
>>> list(reversed(nums))
[7, 3, 2, 9, 6]
>>> nums[::-1]
[7, 3, 2, 9, 6]
Kjører timeit på kommandolinjen
Du kan kjøre timeit
på kommandolinjen ved å bruke syntaksen:
$ python -m timeit -s 'setup-code' -n 'number' -r 'repeat' 'stmt'
Du er pålagt å gi erklæringen stmt
hvis utførelsestid skal måles.
Du kan spesifisere setup
kode ved behov – ved å bruke det korte alternativet -s eller det lange alternativet – oppsett. Oppsettkoden kjøres kun én gang.
De number
ganger for å kjøre setningen: kort alternativ -n eller lang alternativ -antall er valgfritt. Og antall ganger for å gjenta denne syklusen: kort alternativ -r eller lang alternativ - gjenta er også valgfritt.
La oss se ovenstående i aksjon for vårt eksempel:
Her er det å lage listen setup
kode og reversering av listen er setningen som skal tidsbestemmes:
$ python -m timeit -s 'nums=[6,9,2,3,7]' 'list(reversed(nums))'
500000 loops, best of 5: 695 nsec per loop
Når du ikke angir verdier for repeat
, brukes standardverdien 5. Og når du ikke spesifiserer number
, koden kjøres så mange ganger som nødvendig for å nå en total tid på minst 0.2 sekunder.
Dette eksemplet angir eksplisitt antall ganger setningen skal utføres:
$ python -m timeit -s 'nums=[6,9,2,3,7]' -n 100Bu000 'list(reversed(nums))'
100000 loops, best of 5: 540 nsec per loop
Standardverdien på repeat
er 5, men vi kan sette den til en hvilken som helst passende verdi:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' -r 3 'list(reversed(nums))'
500000 loops, best of 3: 663 nsec per loop
La oss også sette tid på listeskjæringsmetoden:
$ python3 -m timeit -s 'nums=[6,9,2,3,7]' 'nums[::-1]'
1000000 loops, best of 5: 142 nsec per loop
Liste-tilnærmingen ser ut til å være raskere (alle eksempler er i Python 3.10 på Ubuntu 22.04).
Kjører timeit i et Python-skript
Her er det tilsvarende å kjøre timeit inne i Python-skriptet:
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}")
De timeit()
callable returnerer utførelsestiden på stmt
forum number
av ganger. Legg merke til at vi eksplisitt kan nevne antall ganger å kjøre, eller gjøre number
ta standardverdien på 1000000.
Output >>
Using reversed() fn.: 0.08982690000000002
Using list slicing: 0.015550800000000004
Dette kjører setningen – uten å gjenta timerfunksjonen – for det spesifiserte number
ganger og returnerer utførelsestiden. Det er også ganske vanlig å bruke time.repeat()
og ta minimumstiden som vist:
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}")
Dette vil gjenta prosessen med å kjøre koden number
av ganger repeat
antall ganger og returnerer minimum utførelsestid. Her har vi 5 repetisjoner på 100000 XNUMX ganger hver.
Output >>
Using reversed() fn.: 0.055375300000000016
Using list slicing: 0.015101400000000043
Vi har sett hvordan timeit kan brukes til å måle utførelsestidene til korte kodebiter. I praksis er det imidlertid mer nyttig å profilere et helt Python-skript.
Dette vil gi oss utføringstidene for alle funksjonene og metodekallene – inkludert innebygde funksjoner og metoder. Så vi kan få et bedre inntrykk av de dyrere funksjonskallene og identifisere muligheter for optimalisering. For eksempel: det kan være et API-kall som er for tregt. Eller en funksjon kan ha en løkke som kan erstattes av et mer pytonisk forståelsesuttrykk.
La oss lære hvordan du profilerer Python-skript ved å bruke cProfile-modulen (også en del av Python-standardbiblioteket).
Tenk på følgende Python-skript:
# 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)
Her har vi tre funksjoner:
func()
som går gjennom en rekke tall og skriver dem ut.another func()
som inneholder en oppfordring tilsleep()
funksjon.useful_func()
som returnerer indeksen til et målnummer i listen (hvis målet er til stede i listen).
Funksjonene ovenfor kalles opp hver gang du kjører main.py-skriptet.
Kjører cProfile på kommandolinjen
Kjør cProfile på kommandolinjen ved å bruke:
python3 -m file-name.py
Her har vi kalt filen main.py:
python3 -m main.py
Å kjøre dette bør gi deg følgende utgang:
Output >> 0 ... 999 Slept for 20 seconds
Og følgende profil:
Her ncalls
refererer til antall anrop til funksjonen og percall
refererer til tiden per funksjonsanrop. Hvis verdien av ncalls
er større enn én, da percall
er gjennomsnittstiden for alle samtaler.
Utførelsestiden for skriptet er dominert av another_func
som bruker den innebygde sleep
funksjonsanrop (sover i 20 sekunder). Det ser vi print
funksjonsanrop er også ganske dyre.
Bruke cProfile i Python-skriptet
Mens du kjører cProfile på kommandolinjen fungerer fint, kan du også legge til profileringsfunksjonaliteten til Python-skriptet. Du kan bruke cProfile sammen med pstats modul for profilering og tilgang til statistikk.
Som en beste praksis for å håndtere ressursoppsett og nedbygging bedre, bruk with-setningen og opprette et profilobjekt som brukes som kontekstbehandling:
# 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()
La oss se nærmere på utdataprofilen som er generert:
Når du profilerer et stort skript, vil det være nyttig å sortere resultatene etter utførelsestid. For å gjøre det kan du ringe sort_stats
på profilobjektet og sorter basert på utførelsestiden:
...
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()
Når du nå kjører skriptet, skal du kunne se resultatene sortert etter tid:
Jeg håper denne guiden hjelper deg å komme i gang med profilering i Python. Husk alltid at optimaliseringer aldri skal gå på bekostning av lesbarhet. Hvis du er interessert i å lære om andre profiler, inkludert tredjeparts Python-pakker, sjekk ut denne artikkel om Python-profiler.
Bala Priya C er en utvikler og teknisk skribent fra India. Hun liker å jobbe i skjæringspunktet mellom matematikk, programmering, datavitenskap og innholdsskaping. Hennes interesseområder og ekspertise inkluderer DevOps, datavitenskap og naturlig språkbehandling. Hun liker å lese, skrive, kode og kaffe! For øyeblikket jobber hun med å lære og dele kunnskapen sin med utviklerfellesskapet ved å skrive veiledninger, veiledninger, meningsartikler og mer.
- SEO-drevet innhold og PR-distribusjon. Bli forsterket i dag.
- PlatoData.Network Vertical Generative Ai. Styrk deg selv. Tilgang her.
- PlatoAiStream. Web3 Intelligence. Kunnskap forsterket. Tilgang her.
- PlatoESG. Bil / elbiler, Karbon, CleanTech, Energi, Miljø, Solenergi, Avfallshåndtering. Tilgang her.
- PlatoHelse. Bioteknologisk og klinisk etterretning. Tilgang her.
- ChartPrime. Hev handelsspillet ditt med ChartPrime. Tilgang her.
- BlockOffsets. Modernisering av eierskap for miljøkompensasjon. Tilgang her.
- kilde: 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
- :er
- :ikke
- 10
- 100000
- 12
- 13
- 15%
- 17
- 19
- 20
- 22
- 7
- 8
- 9
- a
- I stand
- Om oss
- ovenfor
- absolutt
- Tilgang
- ACM
- tvers
- Handling
- legge til
- Alle
- også
- alltid
- an
- og
- noen
- api
- tilnærming
- ER
- områder
- AS
- At
- forfatter
- gjennomsnittlig
- basert
- BE
- før du
- BEST
- Bedre
- både
- innebygd
- men
- by
- ring
- som heter
- Samtaler
- CAN
- Kan få
- Karriere
- CFM
- sjekk
- nærmere
- kode
- Koding
- Kom
- Felles
- samfunnet
- inneholder
- innhold
- innholdsskaping
- kontekst
- bekvemmelighet
- Kostnad
- kombinert
- skape
- Opprette
- skaperverket
- I dag
- syklus
- dato
- datavitenskap
- Misligholde
- Utvikler
- DevOps
- do
- ikke
- hver enkelt
- Hele
- Tilsvarende
- eksempel
- eksempler
- henrette
- gjennomføring
- dyrt
- ekspertise
- uttrykk
- raskere
- Noen få
- filet
- slutt
- Først
- første steg
- etter
- Til
- fra
- funksjon
- funksjonalitet
- funksjoner
- generert
- få
- Gi
- god
- større
- veilede
- Guider
- håndtere
- Ha
- hørt
- hjelpe
- nyttig
- hjelper
- her
- her.
- håp
- Hvordan
- Hvordan
- Men
- HTML
- HTTPS
- i
- Tanken
- identifisere
- if
- importere
- forbedre
- in
- inkludere
- Inkludert
- indeks
- india
- innsiden
- interesse
- interessert
- Interface
- kryss
- IT
- KDnuggets
- kunnskap
- Språk
- stor
- LÆRE
- læring
- minst
- Bibliotek
- Sannsynlig
- liker
- linje
- Liste
- Lang
- Se
- Hoved
- gjøre
- leder
- mange
- math
- Kan..
- måle
- målte
- nevner
- metode
- metoder
- kunne
- minimum
- moduler
- Moduler
- mer
- oppkalt
- Naturlig
- Naturlig språk
- Natural Language Processing
- nødvendig
- nødvendig
- aldri
- Legge merke til..
- nå
- Antall
- tall
- objekt
- å skaffe seg
- of
- Tilbud
- ofte
- on
- gang
- ONE
- bare
- Mening
- Muligheter
- optimalisering
- Alternativ
- or
- Annen
- vår
- ut
- produksjon
- pakker
- del
- for
- stykker
- plato
- Platon Data Intelligence
- PlatonData
- praksis
- presentere
- utskrifter
- prosess
- prosessering
- Profil
- profilering
- Programmering
- prosjekter
- gi
- Python
- kvalitet
- sitere
- område
- å nå
- Lesning
- refererer
- husker
- gjenta
- erstattet
- påkrevd
- ressurs
- Resultater
- retur
- avkastning
- root
- Kjør
- rennende
- går
- s
- Vitenskap
- script
- skript
- sekunder
- seksjoner
- se
- synes
- sett
- sett
- sett
- oppsett
- deling
- hun
- Kort
- bør
- vist
- Enkelt
- langsom
- liten
- So
- Software
- spesifisert
- Standard
- startet
- Uttalelse
- statistikk
- Steps
- egnet
- Super
- syntaks
- T1
- Ta
- tar
- Target
- rive ned
- Teknisk
- enn
- Det
- De
- Dem
- deretter
- Der.
- tredjeparts
- denne
- tre
- Gjennom
- tid
- Tidsbestemt
- ganger
- til
- også
- Totalt
- tutorials
- Ubuntu
- us
- bruke
- brukt
- bruker
- ved hjelp av
- verdi
- Verdier
- we
- når
- mens
- hvem sin
- vil
- med
- arbeid
- virker
- forfatter
- skriving
- du
- Din
- zephyrnet