Після гри з timeit
модулем мені не подобається його інтерфейс, який не такий елегантний порівняно з двома наступними методами.
Наступний код знаходиться в Python 3.
Декоративний метод
Це майже те саме з методом @ Майка. Тут я додаю kwargs
і functools
загортаю, щоб було краще.
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)
Метод контекстного менеджера
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)))
Наприклад, ви можете використовувати його так:
with timeit_context('My profiling code'):
mike = Person()
mike.think()
І код всередині with
блоку буде приурочений.
Висновок
Використовуючи перший метод, ви можете легко прокоментувати декоратора, щоб отримати нормальний код. Однак функція може лише час. Якщо у вас є частина коду, яку ви не знаєте, щоб зробити її функцією, то ви можете вибрати другий метод.
Наприклад, зараз у вас є
images = get_images()
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Тепер ви хочете відстежити bigImage = ...
лінію. Якщо ви зміните його на функцію, це буде:
images = get_images()
bitImage = None
@timeit
def foobar():
nonlocal bigImage
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)
Виглядає не так чудово ... Що робити, якщо ви перебуваєте в Python 2, де немає nonlocal
ключового слова.
Натомість, тут добре підходить використання другого методу:
images = get_images()
with timeit_context('foobar'):
bigImage = ImagePacker.pack(images, width=4096)
drawer.draw(bigImage)