Programmering

Sådan bruges timeit til at profilere Python-kode

Ved design sætter Python bekvemmelighed, læsbarhed og brugervenlighed foran ydeevne. Men det betyder ikke, at du skal nøjes med langsom Python-kode. Der er sandsynligvis noget, du kan gøre for at fremskynde det.

Blandt de tilgængelige værktøjer til profilering af udførelsen af ​​Python-kode er den enkleste timeit modul. timeit bruges til at måle hastigheden af ​​små kodestykker - et par linjer, en funktion - ved at udføre koden tusinder eller endda millioner af gange og rapportere, hvor lang tid disse henrettelser tog at gennemføre.

timeit er mest nyttigt til at sammenligne to eller tre forskellige måder at gøre noget på og se, hvilken der er den hurtigste. For eksempel er en sløjfe, der kører i tusinder af iterationer, en almindelig Python-flaskehals. Hvis du kan finde en måde at fremskynde implementeringen af ​​denne loop - f.eks. Ved at bruge Python-indbyggede i stedet for håndskrevet kode - kan du få en målbar præstationsforbedring.

Et simpelt Python timeit-eksempel

Her er et simpelt eksempel på hvordan timeit arbejder:

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

Dette program sammenligner ydeevnen på to måder at gentage gennem en løkke 100 gange: ved hjælp af Pythons indbyggederækkevidde funktion (f1) og ved at øge en variabel (f2). timeit kører hver af disse tilgange 100.000 gange og giver en samlet køretid i slutningen for hver. Som standard,timeit bruger en million kørsler, men dette eksempel viser, hvordan du kan indstille antallet af kørsler til et hvilket som helst tal, der synes passende.

Resultaterne (fra en Intel i7-3770K-processor):

0.1252315

0.45453989999999994

Det er klart, atrækkevidde tilgang er meget hurtigere med en faktor på ca. 3,75. Dette er ikke overraskende; brug af en indbygget Python giver typisk bedre ydeevne end manuelt at manipulere Python-objekter.

Brug Python timeit ved at sende en streng

En anden måde at bruge påtimeit er at sende en streng, der evalueres som et Python-program:

importtid det

print (timeit.timeit ('for n inden for rækkevidde (100): pass'))

Dette kan også gøres fra kommandolinjen:

python -m timeit "for n i området (100): pass"

I det store og hele er det dog lettere at bruge den teknik, der er vist ovenfor, da du ikke behøver at kløge din kode i en tekststreng.

Python timeit tip

Så nyttigt somtimeit er, husk disse forbehold om, hvordan du bruger det.

Undgå at bruge timeit til profilering af hele programmet

Intet siger digkan ikke gang et helt program medtimeit. Et simpelt 10-linjers script er for eksempel ikke en dårlig kandidat til at blive profileret på denne måde.

Men der er bedre værktøjer til det job - for eksempel PythonscProfil modul, som genererer langt mere detaljerede statistikker om hele programmets ydeevne. timeit fungerer bedst med en enkelt komponent eller et kodestykke - igen, en funktion eller et par kodelinjer. Noget mere end det genererer typisk resultater, der er for støjende og inkonsekvente til at give dig nogen meningsfuld ydeevneinformation.

Hvis det tager mange minutter at gennemføre det program, du profilerer,timeit vil ikke være til stor nytte. For det første vil det tage for lang tid at køre koden mere end et par gange, så de indsamlede tidspunkter vil være meget rå. For to er andre værktøjer bedre egnet til jobbet.

Udfør flere tidskørsler på forskellige maskiner

Programmer kører ikke med samme hastighed hver gang. Moderne computermiljøer indfører meget usikkerhed - konkurrence med andre programmer om ressourcer, cacheadfærd, planlægning osv.timeit forsøger at kompensere for dette ved at udføre koden ad infinitum, men det er stadig en god ide at samle flere forsøg. Du skal køre entimeit profil mange gange, kast de værste og bedste scores og gennemsnit resten.

Endelig hjælper det også med at køre den samme test på forskellige systemer: hvordan vil noget diskbundet opføre sig på en SSD versus en konventionel roterende harddisk? Som med ethvert andet spørgsmål om ydeevne - gæt ikke, test.

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