Po zabawie z timeit
modułem nie podoba mi się jego interfejs, który nie jest tak elegancki w porównaniu do dwóch poniższych metod.
Poniższy kod jest w języku Python 3.
Metoda dekoratora
To jest prawie to samo z metodą @ Mike'a. Tutaj dodaję kwargs
i functools
zawijam, żeby było lepiej.
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)
Metoda menedżera kontekstu
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)))
Na przykład możesz go używać tak, jak:
with timeit_context('My profiling code'):
mike = Person()
mike.think()
Kod w with
bloku będzie mierzony w czasie.
Wniosek
Korzystając z pierwszej metody, możesz codziennie skomentować dekorator, aby uzyskać normalny kod. Jednak może tylko mierzyć czas funkcji. Jeśli masz jakąś część kodu, której nie możesz uczynić z funkcji, możesz wybrać drugą metodę.
Na przykład teraz masz
images = get_images()
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Teraz chcesz ustawić czas na bigImage = ...
linii. Jeśli zmienisz to na funkcję, będzie to:
images = get_images()
bitImage = None
@timeit
def foobar():
nonlocal bigImage
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Wygląda niezbyt dobrze ... A co jeśli jesteś w Pythonie 2, który nie ma nonlocal
słowa kluczowego.
Zamiast tego użycie drugiej metody pasuje tutaj bardzo dobrze:
images = get_images()
with timeit_context('foobar'):
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)