Voici mes conclusions après avoir parcouru de nombreuses bonnes réponses ici ainsi que quelques autres articles.
Premièrement, si vous discutez entre timeit
et time.time
, le timeit
a deux avantages:
timeit
sélectionne la meilleure minuterie disponible sur votre version OS et Python.
timeit
désactive la collecte des ordures, cependant, ce n'est pas quelque chose que vous pouvez ou ne voulez pas.
Maintenant, le problème n'est timeit
pas aussi simple à utiliser, car il nécessite une configuration et les choses deviennent laides lorsque vous avez un tas d'importations. Idéalement, vous voulez juste un décorateur ou utiliser un with
bloc et mesurer le temps. Malheureusement, il n'y a rien de intégré disponible pour cela, vous avez donc deux options:
Option 1: utiliser la bibliothèque timebudget
Le timebudget est une bibliothèque polyvalente et très simple que vous pouvez utiliser en une seule ligne de code après l'installation de pip.
@timebudget # Record how long this function takes
def my_method():
# my code
Option 2: utiliser directement le module de code
J'ai créé ci-dessous un petit module utilitaire.
# utils.py
from functools import wraps
import gc
import timeit
def MeasureTime(f, no_print=False, disable_gc=False):
@wraps(f)
def _wrapper(*args, **kwargs):
gcold = gc.isenabled()
if disable_gc:
gc.disable()
start_time = timeit.default_timer()
try:
result = f(*args, **kwargs)
finally:
elapsed = timeit.default_timer() - start_time
if disable_gc and gcold:
gc.enable()
if not no_print:
print('"{}": {}s'.format(f.__name__, elapsed))
return result
return _wrapper
class MeasureBlockTime:
def __init__(self,name="(block)", no_print=False, disable_gc=False):
self.name = name
self.no_print = no_print
self.disable_gc = disable_gc
def __enter__(self):
self.gcold = gc.isenabled()
if self.disable_gc:
gc.disable()
self.start_time = timeit.default_timer()
def __exit__(self,ty,val,tb):
self.elapsed = timeit.default_timer() - self.start_time
if self.disable_gc and self.gcold:
gc.enable()
if not self.no_print:
print('Function "{}": {}s'.format(self.name, self.elapsed))
return False #re-raise any exceptions
Vous pouvez maintenant chronométrer n'importe quelle fonction simplement en plaçant un décorateur devant:
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
Si vous voulez chronométrer une partie du code, mettez-le simplement dans le with
bloc:
import utils
#somewhere in my code
with utils.MeasureBlockTime("MyBlock"):
#do something time consuming
for i in range(10000):
print(i)
# rest of my code
Avantages:
Il existe plusieurs versions à moitié sauvegardées, je tiens donc à souligner quelques points saillants:
- Utilisez la minuterie de timeit au lieu de time.time pour les raisons décrites précédemment.
- Vous pouvez désactiver GC pendant le chronométrage si vous le souhaitez.
- Decorator accepte les fonctions avec des paramètres nommés ou non.
- Possibilité de désactiver l'impression en mode bloc (utiliser
with utils.MeasureBlockTime() as t
puis t.elapsed
).
- Possibilité de garder gc activé pour le chronométrage des blocs.