Точно измерять функцию времени python
Мне нужно измерить время выполнения определенных частей моей программы (не для отладки, а как функцию в выходе). Точность важна, потому что общее время будет составлять долю секунды.
Я собирался использовать модуль времени, когда я наткнулся на timeit, который утверждает, что позволяет избежать ряда общих ловушек для измерения времени выполнения. К сожалению, у него есть ужасный интерфейс, взяв строку в качестве входной информации, которая тогда будет eval.
Итак, нужно ли использовать этот модуль для точного измерения времени или достаточно времени? И каковы подводные камни, на которые он ссылается?
Спасибо
Ответы
Ответ 1
В соответствии с документацией Python это связано с точностью функции времени в разных операционных системах:
Функция таймера по умолчанию - платформа зависимый. В Windows время time.clock() имеет микросекундную зернистость, но Гранулярность time.time() составляет 1/60 Второй; в Unix, time.clock() имеет 1/100-й частичной гранулярности и time.time() гораздо точнее. На либо платформа, таймер по умолчанию функции измеряют время настенных часов, а не время процессора. Это означает, что другие процессы, выполняемые на одном компьютере может повлиять на сроки... В Unix вы можете используйте time.clock() для измерения времени процессора.
Вытащить непосредственно из timeit.py
кода:
if sys.platform == "win32":
# On Windows, the best timer is time.clock()
default_timer = time.clock
else:
# On most other platforms the best timer is time.time()
default_timer = time.time
Кроме того, он напрямую связан с настройкой кода выполнения для вас. Если вы используете время, вы должны сделать это сами. Это, конечно, экономит ваше время
Настройка тайм-аута:
def inner(_it, _timer):
#Your setup code
%(setup)s
_t0 = _timer()
for _i in _it:
#The code you want to time
%(stmt)s
_t1 = _timer()
return _t1 - _t0
Изменить, только Python 3:
С Python 3.3 вы можете использовать time.perf_counter()
(общесистемное время) или time.process_time()
(время процесса), так же, как вы использовали time.clock()
:
from time import process_time
t = process_time()
#do some stuff
elapsed_time = process_time() - t
Новая функция process_time
не будет включать время, прошедшее во время сна.
Ответ 2
Вы можете создать временной контекст (см. PEP 343), чтобы довольно легко измерить блоки кода.
from __future__ import with_statement
import time
class Timer(object):
def __enter__(self):
self.__start = time.time()
def __exit__(self, type, value, traceback):
# Error handling here
self.__finish = time.time()
def duration_in_seconds(self):
return self.__finish - self.__start
timer = Timer()
with timer:
# Whatever you want to measure goes here
time.sleep(2)
print timer.duration_in_seconds()
Ответ 3
Модуль timeit выглядит так, как будто он предназначен для выполнения тестирования производительности алгоритмов, а не как простой мониторинг приложения. Возможно, ваш лучший вариант - использовать модуль времени, вызвать time.time()
в начале и конце интересующего вас сегмента и вычесть два числа. Имейте в виду, что число, которое вы получаете, может иметь гораздо больше десятичных знаков, чем фактическое разрешение системного таймера.
Ответ 4
Вы просмотрели предоставленный функциональный профиль или cProfile?
http://docs.python.org/library/profile.html
Это дает гораздо более подробную информацию, чем просто печать времени до и после вызова функции. Возможно стоит посмотреть...
Ответ 5
Меня тоже раздражал ужасный интерфейс timeit, поэтому я создал библиотеку для этого, проверьте его тривиальность в использовании
from pythonbenchmark import compare, measure
import time
a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]
def myFunction(something):
time.sleep(0.4)
def myOptimizedFunction(something):
time.sleep(0.2)
# comparing test
compare(myFunction, myOptimizedFunction, 10, input)
# without input
compare(myFunction, myOptimizedFunction, 100)
https://github.com/Karlheinzniebuhr/pythonbenchmark
Ответ 6
В документации также упоминается, что time.clock() и time.time() имеют разное разрешение в зависимости от платформы. В Unix time.clock() измеряет время процессора, а не время настенного времени.
timeit также отключает сбор мусора при запуске тестов, что, вероятно, не является тем, что вы хотите для производственного кода.
Я нахожу, что time.time() достаточно для большинства целей.
Ответ 7
Из Python 2.6 по времени это больше не ограничивается входной строкой. Цитирование документация:
Изменено в версии 2.6: параметры stmt и setup теперь также могут принимать объекты, которые могут быть вызваны без аргументов. Это будет включать вызовы к ним в функции таймера, которые затем будут выполняться с помощью timeit(). Обратите внимание, что в этом случае накладные расходы времени немного больше из-за дополнительных вызовов функций.