Aquí están mis hallazgos después de pasar por muchas buenas respuestas aquí, así como algunos otros artículos.
Primero, si está debatiendo entre timeit
y time.time
, timeit
tiene dos ventajas:
timeit
selecciona el mejor temporizador disponible en su sistema operativo y la versión de Python.
timeit
deshabilita la recolección de basura, sin embargo, esto no es algo que puede desear o no.
Ahora el problema es que timeit
no es tan fácil de usar porque necesita configuración y las cosas se ponen feas cuando tienes un montón de importaciones. Idealmente, solo quieres un decorador o usarwith
bloquear y medir el tiempo. Desafortunadamente, no hay nada incorporado disponible para esto, por lo que tiene dos opciones:
Opción 1: usar la biblioteca timebudget
El timebudget es una biblioteca versátil y muy simple que se puede utilizar sólo en una línea de código después de pepita instalar.
@timebudget # Record how long this function takes
def my_method():
# my code
Opción 2: usar el módulo de código directamente
Creé a continuación un pequeño módulo de utilidad.
# 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
Ahora puede cronometrar cualquier función simplemente colocando un decorador frente a ella:
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
Si desea cronometrar la parte del código, simplemente póngalo dentro del with
bloque:
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
Ventajas:
Hay varias versiones con respaldo medio flotando, así que quiero señalar algunos aspectos destacados:
- Use el temporizador de timeit en lugar de time.time por las razones descritas anteriormente.
- Puede deshabilitar GC durante el tiempo si lo desea.
- Decorator acepta funciones con parámetros con o sin nombre.
- Posibilidad de desactivar la impresión en tiempo de bloque (uso
with utils.MeasureBlockTime() as t
y luego t.elapsed
).
- Capacidad para mantener gc habilitado para el tiempo de bloqueo.