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.12523150.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 detprint (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.