Utilizarea Python Timeit pentru a-ți cronometra codul
Publicat: 2023-01-17În acest tutorial, veți învăța cum să utilizați funcția timeit din modulul timeit al lui Python. Veți învăța cum să cronometrați expresii și funcții simple în Python.
Cronometrarea codului vă poate ajuta să obțineți o estimare a timpului de execuție a unei bucăți de cod și, de asemenea, să identificați secțiunile de cod care trebuie optimizate.
Vom începe prin a învăța sintaxa funcției timeit
a lui Python. Și apoi vom codifica exemple pentru a înțelege cum să-l folosiți pentru a cronometra blocuri de cod și funcții din modulul dvs. Python. Sa incepem.
Cum să utilizați funcția Python timeit
Modulul timeit
face parte din biblioteca standard Python și îl puteți importa:
import timeit
Sintaxa de utilizare a funcției timeit
din modulul timeit
este prezentată mai jos:
timeit.timeit(stmt, setup, number)
Aici:
-
stmt
este fragmentul de cod al cărui timp de execuție urmează să fie măsurat. Puteți să-l specificați ca un șir Python simplu sau un șir cu mai multe linii sau să treceți numele apelabilului. - După cum sugerează și numele,
setup
denotă fragmentul de cod care trebuie să ruleze o singură dată, adesea ca o condiție prealabilă pentru rulareastmt
. De exemplu, să presupunem că calculați timpul de execuție pentru crearea unui tablou NumPy. În acest caz, importareanumpy
este codul desetup
, iar crearea efectivă este instrucțiunea care urmează să fie cronometrată. -
number
parametrului indică de câte ori este rulatstmt
. Valoarea implicită anumber
este 1 milion (1000000), dar puteți seta și acest parametru la orice altă valoare la alegere.
Acum că am învățat sintaxa pentru a folosi funcția timeit()
, să începem să codificăm câteva exemple.
Cronometrarea expresiilor simple Python

În această secțiune, vom încerca să măsurăm timpul de execuție al expresiilor simple Python folosind timeit.
Porniți un Python REPL și rulați următoarele exemple de cod. Aici, calculăm timpul de execuție al operațiunilor de exponențiere și împărțire a etajului pentru 10000 și 100000 de rulări.
Observați că trecem instrucțiunea pentru a fi cronometrată ca șir Python și folosim punct și virgulă pentru a separa diferitele expresii din instrucțiune.
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764
Rularea Python timeit la linia de comandă
De asemenea, puteți utiliza timeit
la linia de comandă. Iată echivalentul în linia de comandă al apelului funcției timeit:
$ python-m timeit -n [number] -s [setup] [stmt]
-
python -m timeit
reprezintă că rulămtimeit
ca modul principal. -
n
este o opțiune de linie de comandă care indică de câte ori ar trebui să ruleze codul. Acesta este echivalent cu argumentulnumber
din apelul funcțieitimeit()
. - Puteți utiliza opțiunea
-s
pentru a defini codul de configurare.
Aici, rescriem exemplul anterior folosind echivalentul liniei de comandă:
$ python -m timeit -n 100000 '3**4;3//4' 100000 loops, best of 5: 35.8 nsec per loop
În acest exemplu, calculăm timpul de execuție al funcției încorporate len()
. Inițializarea șirului este codul de configurare care este transmis folosind opțiunea s
.
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)' 100000 loops, best of 5: 239 nsec per loop
În ieșire, observați că obținem timpul de execuție pentru cel mai bun dintre 5 rulări. Ce inseamna asta? Când rulați timeit
la linia de comandă, opțiunea de repeat
r
este setată la valoarea implicită de 5. Aceasta înseamnă că execuția stmt
pentru number
specificat de ori este repetată de cinci ori și este returnat cel mai bun dintre timpii de execuție.
Analiza metodelor de inversare a șirurilor folosind timeit
Când lucrați cu șiruri Python, poate doriți să le inversați. Cele mai comune două abordări ale inversării șirurilor sunt următoarele:
- Folosind string slicing
- Folosind funcția
reversed()
și metodajoin()

Inversați șirurile Python folosind String Slicing
Să vedem cum funcționează tăierea șirurilor și cum o puteți folosi pentru a inversa un șir Python. Folosind sintaxa some-string[start:stop]
returnează o porțiune a șirului începând de la start
indexului și extinzându-se până la indexul stop-1
. Să luăm un exemplu.
Luați în considerare următorul șir „Python”. Șirul este de lungime 6, iar lista de indici este de la 0, 1, 2 până la 5.

>>> string_1 = 'Python'
Când specificați atât valorile de start
, cât și cele de stop
, obțineți o porțiune de șir care se extinde de la start
la stop-1
. Prin urmare, string_1[1:4]
returnează „yth”.

>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
Când nu specificați valoarea de start
, este utilizată valoarea de start
implicită de zero, iar felia începe la indicele zero și se extinde până la stop - 1
.

Aici, valoarea de stop
este 3, deci felia începe de la indicele 0 și urcă până la indicele 2.
>>> string_1[:3] 'Pyt'
Când nu includeți indexul de stop
, vedeți că felia începe de la indexul de start
(1) și se extinde până la sfârșitul șirului.

>>> string_1[1:] 'ython'
Ignorarea ambelor valori de start
și de stop
returnează o porțiune din întregul șir.


>>> string_1[::] 'Python'
Să creăm o felie cu valoarea step
. Setați valorile de start
, stop
și step
la 1, 5 și, respectiv, 2. Obținem o felie de șir care începe la 1 care se extinde până la 4 (excluzând punctul final 5) care conține fiecare al doilea caracter .

>>> string_1[1:5:2] 'yh'
Când utilizați un pas negativ, puteți obține o felie începând de la sfârșitul șirului. Cu pasul setat la -2, string_1[5:2:-2]
oferă următoarea felie:

>>> string_1[5:2:-2] 'nh'
Deci, pentru a obține o copie inversată a șirului, sărim peste valorile de start
și stop
și setăm pasul la -1, așa cum se arată:
>>> string_1[::-1] 'nohtyP'
În rezumat:
string[::-1]
returnează o copie inversată a șirului.
Inversarea șirurilor folosind funcții încorporate și metode cu șiruri
Funcția încorporată reversed()
în Python va returna un iterator invers peste elementele șirului.
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>
Deci, puteți trece prin iteratorul invers folosind o buclă for:
for char in reversed(string_1): print(char)
Și accesați elementele șirului în ordine inversă.
# Output n o h t y P
Apoi, puteți apela metoda join()
pe iteratorul invers cu sintaxa: <sep>.join(reversed(some-string))
.
Fragmentul de cod de mai jos arată câteva exemple în care separatorul este o cratimă și, respectiv, un spațiu alb.
>>> '-'.join(reversed(string1)) 'nohtyP' >>> ' '.join(reversed(string1)) 'nohty P'
Aici, nu vrem niciun separator; deci setați separatorul la un șir gol pentru a obține o copie inversată a șirului:
>>> ''.join(reversed(string1)) 'nohtyP'
Folosind
''.join(reversed(some-string))
returnează o copie inversată a șirului.
Compararea timpilor de execuție folosind timeit
Până acum, am învățat două abordări pentru a inversa șirurile Python. Dar care dintre ele este mai rapid? Să aflăm.
Într-un exemplu anterior în care am cronometrat expresii Python simple, nu aveam niciun cod setup
. Aici, inversăm șirul Python. În timp ce operația de inversare a șirului rulează de numărul de ori specificat de number
, codul de setup
este inițializarea șirului care va rula o singură dată.
>>> import timeit >>> timeit.timeit(stmt = 'string_1[::-1]', setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302
Pentru același număr de rulări pentru inversarea șirului dat, abordarea tăierii șirurilor este mai rapidă decât utilizarea metodei join()
și a funcției reversed()
.
Timingul funcțiilor Python Folosind timeit

În această secțiune, să învățăm cum să cronometram funcțiile Python cu funcția timeit. Având în vedere o listă de șiruri, următoarea funcție hasDigit
returnează lista de șiruri care au cel puțin o cifră.
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit
Acum am dori să măsurăm timpul de execuție al acestei funcții Python hasDigit()
folosind timeit
.
Să identificăm mai întâi declarația care urmează să fie cronometrată ( stmt
). Este apelul la funcția hasDigit()
cu o listă de șiruri ca argument. În continuare, să definim codul de configurare . Poți ghici care ar trebui să fie codul de setup
?
Pentru ca apelul de funcție să ruleze cu succes, codul de configurare ar trebui să includă următoarele:
- Definiția funcției
hasDigit()
- Inițializarea listei de argumente de șiruri
Să definim codul de setup
în șirul de configurare, așa cum se arată mai jos:
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """
Apoi, putem folosi funcția timeit
și obținem timpul de execuție al funcției hasDigit()
pentru 100000 de rulări.
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output 0.2810094920000097
Concluzie
Ați învățat cum să utilizați funcția timeit de la Python pentru a cronometra expresii, funcții și alte apelabile. Acest lucru vă poate ajuta să vă comparați codul, să comparați timpii de execuție ale diferitelor implementări ale aceleiași funcții și multe altele.
Să revizuim ceea ce am învățat în acest tutorial. Puteți utiliza funcția timeit()
cu sintaxa timeit.timeit(stmt=...,setup=...,number=...)
. Alternativ, puteți rula timeit la linia de comandă pentru a cronometra fragmentele de cod scurt.
Ca pas următor, puteți explora cum să utilizați alte pachete de profilare Python, cum ar fi line-profiler și memprofiler, pentru a vă profila codul pentru timp și, respectiv, memorie.
Apoi, aflați cum să calculați diferența de timp în Python.