После игры с модулем timeit
мне не нравится его интерфейс, который не такой элегантный по сравнению со следующими двумя методами.
Следующий код написан на Python 3.
Метод декоратора
Это почти то же самое с методом @ Майка. Здесь я добавляю kwargs
и functools
wrap, чтобы сделать его лучше.
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)