Programmering

Hvordan bruke timeit til å profilere Python-kode

Etter design setter Python bekvemmelighet, lesbarhet og brukervennlighet foran ytelse. Men det betyr ikke at du bør nøye deg med treg Python-kode. Det er sannsynligvis noe du kan gjøre for å øke hastigheten.

Blant verktøyene som er tilgjengelige for profilering av ytelsen til Python-kode, er det enkleste timeit modul. timeit brukes til å måle hastigheten til små kodebiter - noen få linjer, en funksjon - ved å utføre koden tusenvis eller til og med millioner av ganger og rapportere hvor lang tid disse henrettelsene tok å fullføre.

timeit er mest nyttig for å sammenligne to eller tre forskjellige måter å gjøre noe på og se hvilken som er raskest. For eksempel er en løkke som går i tusenvis av iterasjoner en vanlig Python-flaskehals. Hvis du finner en måte å øke hastigheten på implementeringen av den sløyfen - for eksempel ved å bruke Python-innebygde i stedet for håndskrevet kode - kan du få en målbar ytelsesforbedring.

Et enkelt Python timeit-eksempel

Her er et enkelt eksempel på hvordan timeit virker:

def f1 (): for n i området (100): pass def f2 (): n = 0 mens n <100: n + = 1 hvis __name__ == "__main__": importtid til utskrift (timeit.timeit (f1, number = 100000)) utskrift (timeit.timeit (f2, nummer = 100000)) 

Dette programmet sammenligner ytelsen på to måter å gjenta gjennom en løkke 100 ganger: ved å bruke Pythons innebygdeområde funksjon (f1), og ved å øke en variabel (f2). timeit kjører hver av disse tilnærmingene 100.000 ganger, og gir en total kjøretid på slutten for hver. Som standard,timeit bruker en million løp, men dette eksemplet viser hvordan du kan angi antall løp til en hvilken som helst figur som virker passende.

Resultatene (fra en Intel i7-3770K-prosessor):

0.1252315

0.45453989999999994

Klartområde tilnærming er mye raskere, med en faktor på ca 3,75. Dette er ikke overraskende; å bruke en innebygd Python gir vanligvis bedre ytelse enn manuell manipulering av Python-objekter.

Bruk Python timeit ved å sende en streng

En annen måte å bruketimeit er å sende en streng som evalueres som et Python-program:

importer tid

skriv ut (timeit.timeit ('for n i området (100): pass'))

Dette kan også gjøres fra kommandolinjen:

python -m timeit "for n i rekkevidde (100): pass"

I det store og hele er det imidlertid enklere å bruke teknikken vist ovenfor, siden du ikke trenger å klø koden i en tekststreng.

Python timeit tips

Like nyttig somtimeit er, husk disse forbeholdene om hvordan du bruker den.

Unngå å bruke timeit til profilering av hele programmet

Ingenting sier degkan ikke tid et helt program medtimeit. Et enkelt 10-linjers skript er for eksempel ikke en dårlig kandidat for å bli profilert på denne måten.

Men det er bedre verktøy for den jobben - for eksempel PythonscProfil modul, som genererer langt mer detaljert statistikk om hele programmets ytelse. timeit fungerer best med en enkelt komponent eller kodebit - igjen, en funksjon eller noen få kodelinjer. Noe mer enn det vil vanligvis generere resultater som er for støyende og inkonsekvente til å gi deg noen meningsfylt ytelsesinformasjon.

Hvis programmet du tar, tar mange minutter å fullføre,timeit vil ikke være til stor nytte. For det første vil det ta for lang tid å kjøre koden mer enn noen få ganger, så tidene som blir hentet vil være veldig rå. For to er andre verktøy bedre egnet til jobben.

Utfør flere gangkjøringer på forskjellige maskiner

Programmene kjører ikke i samme hastighet hver gang. Moderne databehandlingsmiljøer introduserer mye usikkerhet - konkurranse med andre programmer for ressurser, hurtigbufferadferd, planlegging og så videre.timeit prøver å kompensere for dette ved å utføre koden ad infinitum, men det er fortsatt en god ide å samle flere forsøk. Du burde kjøre entimeit profil mange ganger, kast ut de verste og beste resultatene, og gjennomsnitt resten.

Til slutt hjelper det også å kjøre den samme testen på forskjellige systemer: hvordan vil noe diskbundet oppføre seg på en SSD kontra en konvensjonell spinnende harddisk? Som med alle andre spørsmål om ytelse - ikke gjett, test.

$config[zx-auto] not found$config[zx-overlay] not found