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