Dopo aver giocato con il timeit
modulo, non mi piace la sua interfaccia, che non è così elegante rispetto ai due metodi seguenti.
Il codice seguente è in Python 3.
Il metodo del decoratore
Questo è quasi lo stesso con il metodo di @ Mike. Qui aggiungo kwargs
e functools
avvolgo per renderlo migliore.
def timeit(func):
@functools.wraps(func)
def newfunc(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
elapsedTime = time.time() - startTime
print('function [{}] finished in {} ms'.format(
func.__name__, int(elapsedTime * 1000)))
return newfunc
@timeit
def foobar():
mike = Person()
mike.think(30)
Il metodo del gestore di contesto
from contextlib import contextmanager
@contextmanager
def timeit_context(name):
startTime = time.time()
yield
elapsedTime = time.time() - startTime
print('[{}] finished in {} ms'.format(name, int(elapsedTime * 1000)))
Ad esempio, puoi usarlo come:
with timeit_context('My profiling code'):
mike = Person()
mike.think()
E il codice all'interno del with
blocco verrà temporizzato.
Conclusione
Usando il primo metodo, puoi facilmente commentare il decoratore per ottenere il codice normale. Tuttavia, può solo cronometrare una funzione. Se hai una parte di codice che non sai come renderlo una funzione, puoi scegliere il secondo metodo.
Ad esempio, ora hai
images = get_images()
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Ora vuoi cronometrare la bigImage = ...
linea. Se lo cambi in una funzione, sarà:
images = get_images()
bitImage = None
@timeit
def foobar():
nonlocal bigImage
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Non sembra così eccezionale ... E se fossi in Python 2, che non ha nonlocal
parole chiave.
Invece, l'uso del secondo metodo si adatta molto bene qui:
images = get_images()
with timeit_context('foobar'):
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)