Come usare timeit per profilare il codice Python

In base alla progettazione, Python mette convenienza, leggibilità e facilità d'uso prima delle prestazioni. Ma questo non significa che dovresti accontentarti di un codice Python lento. Probabilmente c'è qualcosa che puoi fare per accelerarlo.

Tra gli strumenti disponibili per profilare le prestazioni del codice Python, il più semplice è il timeitmodulo. timeitviene utilizzato per misurare la velocità di piccoli frammenti di codice - poche righe, una funzione - eseguendo il codice migliaia o addirittura milioni di volte e riportando quanto tempo è stato necessario per completare tali esecuzioni.

timeitè molto utile per confrontare due o tre modi diversi di fare qualcosa e vedere qual è il più veloce. Ad esempio, un ciclo che viene eseguito per migliaia di iterazioni è un collo di bottiglia comune in Python. Se riesci a trovare un modo per accelerare l'implementazione di quel ciclo, ad esempio utilizzando i built-in Python invece del codice scritto a mano, potresti ottenere un miglioramento misurabile delle prestazioni.

Un semplice esempio di timeit in Python

Ecco un semplice esempio di come timeitfunziona:

def f1 (): for n nell'intervallo (100): pass def f2 (): n = 0 mentre n <100: n + = 1 if __name__ == "__main__": import timeit print (timeit.timeit (f1, number = 100000)) print (timeit.timeit (f2, number = 100000)) 

Questo programma confronta le prestazioni di due modi per eseguire l'iterazione di un ciclo 100 volte: utilizzando la funzione incorporata di Python  range ( f1) e incrementando una variabile ( f2). timeit esegue ciascuno di questi approcci 100.000 volte e fornisce un runtime totale alla fine per ciascuno. Per impostazione predefinita,  timeit utilizza un milione di esecuzioni, ma questo esempio mostra come è possibile impostare il numero di esecuzioni su qualsiasi cifra che sembra appropriata.

I risultati (da un processore Intel i7-3770K):

0.1252315

0.45453989999999994

Chiaramente l'  range approccio è molto più veloce, di un fattore di circa 3,75. Questo non è sorprendente; l'utilizzo di un built-in Python in genere produce prestazioni migliori rispetto alla manipolazione manuale di oggetti Python.

Usa Python timeit passando una stringa

Un altro modo per utilizzare  timeit è passare una stringa che viene valutata come un programma Python:

import timeit

print (timeit.timeit ('for n in range (100): pass'))

Questo può essere fatto anche dalla riga di comando:

python -m timeit "per n nell'intervallo (100): pass"

Nel complesso, tuttavia, è più facile usare la tecnica mostrata sopra, poiché non è necessario inserire goffamente il codice in una stringa di testo.

Suggerimenti per Python timeit

Per quanto utile  timeit sia, tieni presente questi avvertimenti su come usarlo.

Evita di utilizzare timeit per la profilazione dell'intero programma

Niente dice che  non puoi  cronometrare un intero programma  timeit. Un semplice script di 10 righe, ad esempio, non è un cattivo candidato per essere profilato in questo modo.

Ma ci sono strumenti migliori per quel lavoro, ad esempio il cProfile modulo di Python  , che genera statistiche molto più dettagliate sulle prestazioni dell'intero programma. timeit funziona meglio con un singolo componente o frammento di codice, ancora una volta, una funzione o poche righe di codice. Qualunque cosa in più genererà in genere risultati troppo rumorosi e incoerenti per fornire informazioni significative sulle prestazioni.

Inoltre, se il programma di cui stai profilando richiede molti minuti per essere completato,  timeit non sarà di grande utilità. Per uno, ci vorrà troppo tempo per eseguire il codice più di un paio di volte, quindi i tempi raccolti saranno molto rozzi. Per due, altri strumenti sono più adatti al lavoro.

Esegui più volte l'esecuzione su macchine diverse

I programmi non vengono eseguiti alla stessa velocità ogni volta. Gli ambienti informatici moderni introducono molta incertezza: concorrenza con altri programmi per le risorse, comportamenti della cache, pianificazione e così via. timeit cerca di compensare ciò eseguendo il codice all'infinito, ma è comunque una buona idea aggregare più prove. Dovresti eseguire un  timeit profilo molte volte, eliminare i punteggi migliori e peggiori e fare la media del resto.

Infine, aiuta anche a eseguire lo stesso test su sistemi diversi: come si comporterà qualcosa legato al disco su un SSD rispetto a un disco rigido rotante convenzionale? Come per qualsiasi altra domanda sulle prestazioni, non indovinare, prova.