Comment utiliser timeit pour profiler le code Python

De par sa conception, Python place la commodité, la lisibilité et la facilité d'utilisation avant les performances. Mais cela ne signifie pas que vous devez vous contenter d'un code Python lent. Vous pouvez probablement faire quelque chose pour l'accélérer.

Parmi les outils disponibles pour profiler les performances du code Python, le plus simple est le timeitmodule. timeitest utilisé pour mesurer la vitesse de petits extraits de code - quelques lignes, une fonction - en exécutant le code des milliers, voire des millions de fois et en indiquant combien de temps ces exécutions ont pris pour se terminer.

timeitest très utile pour comparer deux ou trois façons différentes de faire quelque chose et voir laquelle est la plus rapide. Par exemple, une boucle qui s'exécute sur des milliers d'itérations est un goulot d'étranglement Python courant. Si vous pouvez trouver un moyen d'accélérer la mise en œuvre de cette boucle - par exemple, en utilisant des composants intégrés Python au lieu d'un code manuscrit - vous pourriez obtenir une amélioration mesurable des performances.

Un exemple simple de timeit en Python

Voici un exemple simple de timeitfonctionnement:

def f1 (): for n in range (100): pass def f2 (): n = 0 while n <100: n + = 1 if __name__ == "__main__": import timeit print (timeit.timeit (f1, number = 100000)) impression (timeit.timeit (f2, nombre = 100000)) 

Ce programme compare les performances de deux façons d'itérer une boucle 100 fois: en utilisant la fonction intégrée de Python  range ( f1) et en incrémentant une variable ( f2). timeit exécute chacune de ces approches 100 000 fois et fournit un temps d'exécution total à la fin pour chacune. Par défaut,  timeit utilise un million d'exécutions, mais cet exemple montre comment vous pouvez définir le nombre d'exécutions sur n'importe quel chiffre qui vous semble approprié.

Les résultats (à partir d'un processeur Intel i7-3770K):

0,1252315

0,45453989999999994

De toute évidence, l'  range approche est beaucoup plus rapide, d'un facteur d'environ 3,75. Ce n'est pas surprenant; l'utilisation d'un Python intégré donne généralement de meilleures performances que la manipulation manuelle d'objets Python.

Utilisez Python timeit en passant une chaîne

Une autre façon d'utiliser  timeit est de passer une chaîne qui est évaluée comme un programme Python:

import timeit

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

Cela peut également être fait à partir de la ligne de commande:

python -m timeit "pour n dans la plage (100): passer"

Dans l'ensemble, cependant, il est plus facile d'utiliser la technique indiquée ci-dessus, car vous n'avez pas besoin de ferrer maladroitement votre code dans une chaîne de texte.

Astuces Python Timeit

Aussi utile  timeit soit-il, gardez à l'esprit ces mises en garde sur la façon de l'utiliser.

Évitez d'utiliser timeit pour le profilage de l'ensemble du programme

Rien ne dit que vous  ne pouvez pas  chronométrer un programme entier avec  timeit. Un simple script de 10 lignes, par exemple, n'est pas un mauvais candidat pour être profilé de cette façon.

Mais il existe de meilleurs outils pour ce travail - par exemple, le cProfile module Python  , qui génère des statistiques beaucoup plus détaillées sur les performances de l'ensemble de votre programme. timeit fonctionne mieux avec un seul composant ou extrait de code - encore une fois, une fonction ou quelques lignes de code. Rien de plus que cela générera généralement des résultats trop bruyants et incohérents pour vous donner des informations significatives sur les performances.

De plus, si le programme que vous profilez prend plusieurs minutes,  timeit il ne sera pas d'une grande utilité. D'une part, il faudra trop de temps pour exécuter le code plusieurs fois, de sorte que les délais glanés seront très bruts. Pour deux, d'autres outils sont mieux adaptés au travail.

Effectuer plusieurs exécutions timeit sur différentes machines

Les programmes ne fonctionnent pas à la même vitesse à chaque fois. Les environnements informatiques modernes introduisent beaucoup d'incertitude - concurrence avec d'autres programmes pour les ressources, les comportements de cache, la planification, etc. timeit essaie de compenser cela en exécutant le code à l'infini, mais c'est toujours une bonne idée d'agréger plusieurs essais. Vous devez exécuter un  timeit profil plusieurs fois, jeter les pires et meilleurs scores et faire la moyenne du reste.

Enfin, il est également utile d'exécuter le même test sur différents systèmes: comment se comportera un élément lié au disque sur un SSD par rapport à un disque dur rotatif classique? Comme pour toute autre question sur les performances - ne devinez pas, testez.