Hur man använder timeit för att profilera Python-kod

Genom design sätter Python bekvämlighet, läsbarhet och användarvänlighet framför prestanda. Men det betyder inte att du ska nöja dig med långsam Python-kod. Det finns förmodligen något du kan göra för att påskynda det.

Bland de verktyg som finns tillgängliga för profilering av prestanda för Python-kod är det enklaste timeitmodulen. timeitanvänds för att mäta hastigheten för små kodavsnitt - några rader, en funktion - genom att utföra koden tusentals eller till och med miljoner gånger och rapportera hur lång tid dessa avrättningar tog att slutföra.

timeitär mest användbart för att jämföra två eller tre olika sätt att göra något och se vilket som är snabbast. Till exempel är en slinga som körs för tusentals iterationer en vanlig Python-flaskhals. Om du kan hitta ett sätt att påskynda implementeringen av den slingan - säg genom att använda Python-inbyggda istället för handskriven kod - kan du få en mätbar prestationsförbättring.

Ett enkelt Python timeit-exempel

Här är ett enkelt exempel på hur det timeitfungerar:

def f1 (): för n i intervallet (100): passera def f2 (): n = 0 medan n <100: n + = 1 om __name__ == "__main__": importtid för utskrift (timeit.timeit (f1, number = 100000)) skriv ut (timeit.timeit (f2, antal = 100000)) 

Detta program jämför prestanda på två sätt att iterera genom en slinga 100 gånger: genom att använda Pythons inbyggda  range funktion ( f1) och genom att öka en variabel ( f2). timeit kör var och en av dessa tillvägagångssätt 100 000 gånger och ger en total körtid i slutet för varje. Som standard  timeit använder en miljon körningar, men det här exemplet visar hur du kan ställa in antalet körningar till vilken figur som helst som verkar lämplig.

Resultaten (från en Intel i7-3770K-processor):

0,12252315

0,45453989999999994

Uppenbarligen är  range tillvägagångssättet mycket snabbare, med en faktor på cirka 3,75. Detta är inte förvånande; att använda en inbyggd Python ger vanligtvis bättre prestanda än att manuellt manipulera Python-objekt.

Använd Python timeit genom att skicka en sträng

Ett annat sätt att använda  timeit är att skicka en sträng som utvärderas som ett Python-program:

importera tid det

skriv ut (timeit.timeit ('för n inom intervallet (100): pass'))

Detta kan också göras från kommandoraden:

python -m timeit "för n inom intervall (100): pass"

På det hela taget är det dock lättare att använda tekniken som visas ovan, eftersom du inte behöver klämma din kod i en textsträng.

Python timeit tips

Så användbart som det  timeit är, kom ihåg dessa försiktighetsåtgärder om hur du använder det.

Undvik att använda timeit för hela programprofileringen

Ingenting säger att du  inte kan  tid ett helt program med  timeit. Ett enkelt 10-rads manus är till exempel inte en dålig kandidat för att profileras på detta sätt.

Men det finns bättre verktyg för det jobbet - till exempel Pythons  cProfile modul, som genererar mycket mer detaljerad statistik om hela programmets prestanda. timeit fungerar bäst med en enda komponent eller kodavsnitt - igen, en funktion eller några kodrader. Allt mer än det genererar vanligtvis resultat som är för bullriga och inkonsekventa för att ge dig någon meningsfull prestationsinformation.

Om programmet du profilerar tar många minuter att slutföra  timeit kommer det inte att vara till stor nytta. För det första tar det för lång tid att köra koden mer än ett par gånger, så de samlade tidpunkterna blir väldigt råa. För två passar andra verktyg bättre för jobbet.

Utför flera tidskörningar på olika maskiner

Program körs inte i samma hastighet varje gång. Moderna datormiljöer medför mycket osäkerhet - konkurrens med andra program för resurser, cache-beteende, schemaläggning och så vidare. timeit försöker kompensera för detta genom att utföra koden ad infinitum, men det är fortfarande en bra idé att samla flera försök. Du bör köra en  timeit profil många gånger, slänga ut de värsta och bästa poängen och genomsnittlig resten.

Slutligen hjälper det också att köra samma test på olika system: hur kommer något diskbundet att fungera på en SSD jämfört med en konventionell snurrande hårddisk? Som med alla andra frågor om prestanda - gissa inte, testa.