Измерение прошедшего времени с помощью модуля Time
С помощью модуля времени в Python можно измерить прошедшее время? Если так, то как мне это сделать?
Мне нужно сделать это так, чтобы, если курсор находился в виджете в течение определенной продолжительности, происходило событие.
7 ответов
start_time = time.time()
# your code
elapsed_time = time.time() - start_time
Вы также можете написать простой декоратор, чтобы упростить измерение времени выполнения различных функций:
import time
from functools import wraps
PROF_DATA = {}
def profile(fn):
@wraps(fn)
def with_profiling(*args, **kwargs):
start_time = time.time()
ret = fn(*args, **kwargs)
elapsed_time = time.time() - start_time
if fn.__name__ not in PROF_DATA:
PROF_DATA[fn.__name__] = [0, []]
PROF_DATA[fn.__name__][0] += 1
PROF_DATA[fn.__name__][1].append(elapsed_time)
return ret
return with_profiling
def print_prof_data():
for fname, data in PROF_DATA.items():
max_time = max(data[1])
avg_time = sum(data[1]) / len(data[1])
print "Function %s called %d times. " % (fname, data[0]),
print 'Execution time max: %.3f, average: %.3f' % (max_time, avg_time)
def clear_prof_data():
global PROF_DATA
PROF_DATA = {}
Использование:
@profile
def your_function(...):
...
Вы можете профилировать более одной функции одновременно. Затем для печати измерений просто вызовите print_prof_data():
time.time()
сделаю работу.
import time
start = time.time()
# run your code
end = time.time()
elapsed = end - start
Возможно, вы захотите взглянуть на этот вопрос, но я не думаю, что это будет необходимо.
Для пользователей, которые хотят лучшего форматирования,
import time
start_time = time.time()
# your script
elapsed_time = time.time() - start_time
time.strftime("%H:%M:%S", time.gmtime(elapsed_time))
распечатает, в течение 2 секунд:
'00:00:02'
и на 7 минут одну секунду:
'00:07:01'
обратите внимание, что минимальная единица времени с gmtime - секунды. Если вам нужны микросекунды, учтите следующее:
import datetime
start = datetime.datetime.now()
# some code
end = datetime.datetime.now()
elapsed = end - start
print(elapsed)
# or
print(elapsed.seconds,":",elapsed.microseconds)
документация strftime
Для лучшего измерения прошедшего времени (начиная с Python 3.3) используйте time.perf_counter()
,
Возвращает значение (в долях секунды) счетчика производительности, то есть часов с наибольшим доступным разрешением для измерения короткой длительности. Он включает время, прошедшее во время сна, и является общесистемным. Контрольная точка возвращаемого значения не определена, поэтому допустима только разница между результатами последовательных вызовов.
Для измерений порядка часов / дней вам не нужно разрешение до секунды, поэтому используйте time.monotonic()
вместо.
Возвращает значение (в долях секунды) монотонных часов, т.е. часов, которые не могут двигаться назад. На часы не влияют обновления системных часов. Контрольная точка возвращаемого значения не определена, поэтому допустима только разница между результатами последовательных вызовов.
Во многих реализациях это может быть одно и то же.
До 3.3 вы застряли с time.clock()
,
В Unix верните текущее время процессора в виде числа с плавающей запятой, выраженного в секундах. Точность, и фактически само определение значения "процессорного времени", зависит от точности функции C с тем же именем.
В Windows эта функция возвращает настенные часы, прошедшие с момента первого вызова этой функции, в виде числа с плавающей запятой на основе функции Win32 QueryPerformanceCounter(). Разрешение обычно лучше, чем одна микросекунда.
Обновление для Python 3.7
Новым в Python 3.7 является PEP 564. Добавлены новые функции времени с наносекундным разрешением.
Их использование может дополнительно устранить ошибки округления и с плавающей запятой, особенно если вы измеряете очень короткие периоды или если ваше приложение (или машина Windows) работает долго.
Разрешение начинает ухудшаться на perf_counter()
примерно через 100 дней. Так, например, после года безотказной работы самый короткий интервал (больше 0), который он может измерить, будет больше, чем когда он начался.
Для более длительного периода.
import time
start_time = time.time()
...
e = int(time.time() - start_time)
print('{:02d}:{:02d}:{:02d}'.format(e // 3600, (e % 3600 // 60), e % 60))
будет печатать
00:03:15
если более 24 часов
25:33:57
Это вдохновлено ответом Рутгера Хофсте. Спасибо Рутгер!
В программировании есть 2 основных способа измерения времени с разными результатами:
>>> print(time.process_time()); time.sleep(10); print(time.process_time())
0.11751394000000001
0.11764988400000001 # took 0 seconds and a bit
>>> print(time.perf_counter()); time.sleep(10); print(time.perf_counter())
3972.465770326
3982.468109075 # took 10 seconds and a bit
Время процессора: это время, в течение которого данный процесс активно выполняется на ЦП. Спящий режим, ожидание веб-запроса или время, когда выполняются только другие процессы, этому не повлияют.
- Использовать
time.process_time()
- Использовать
Время настенных часов: это относится к тому, сколько времени прошло "на часах, висящих на стене", то есть вне реального времени.
Использовать
time.perf_counter()
time.time()
также измеряет время на настенных часах, но их можно сбросить, чтобы вы могли вернуться во времениtime.monotonic()
не может быть сброшен (монотонный = идет только вперед), но имеет меньшую точность, чемtime.perf_counter()
Вам нужно импортировать время, а затем использовать метод time.time(), чтобы узнать текущее время.
import time
start_time=time.time() #taking current time as starting time
#here your code
elapsed_time=time.time()-start_time #again taking current time - starting time
Еще один хороший способ рассчитать время - использовать структуру с python.
Структура автоматически вызывает методы __enter__ и __exit__, и это именно то, что нам нужно для определения времени.
Давайте создадим класс Timer.
from time import time
class Timer():
def __init__(self, message):
self.message = message
def __enter__(self):
self.start = time()
return None # could return anything, to be used like this: with Timer("Message") as value:
def __exit__(self, type, value, traceback):
elapsed_time = (time() - self.start) * 1000
print(self.message.format(elapsed_time))
Затем можно использовать класс Timer следующим образом:
with Timer("Elapsed time to compute some prime numbers: {}ms"):
primes = []
for x in range(2, 500):
if not any(x % p == 0 for p in primes):
primes.append(x)
print("Primes: {}".format(primes))
Результат следующий:
Простые числа: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499]
Прошедшее время для вычисления некоторых простых чисел: 5.01704216003418ms
Ответ Вадима Шендера великолепен. Вы также можете использовать более простой декоратор, как показано ниже:
import datetime
def calc_timing(original_function):
def new_function(*args,**kwargs):
start = datetime.datetime.now()
x = original_function(*args,**kwargs)
elapsed = datetime.datetime.now()
print("Elapsed Time = {0}".format(elapsed-start))
return x
return new_function()
@calc_timing
def a_func(*variables):
print("do something big!")
Вот обновление умного кода Вадима Шендера с табличным выводом:
import collections
import time
from functools import wraps
PROF_DATA = collections.defaultdict(list)
def profile(fn):
@wraps(fn)
def with_profiling(*args, **kwargs):
start_time = time.time()
ret = fn(*args, **kwargs)
elapsed_time = time.time() - start_time
PROF_DATA[fn.__name__].append(elapsed_time)
return ret
return with_profiling
Metrics = collections.namedtuple("Metrics", "sum_time num_calls min_time max_time avg_time fname")
def print_profile_data():
results = []
for fname, elapsed_times in PROF_DATA.items():
num_calls = len(elapsed_times)
min_time = min(elapsed_times)
max_time = max(elapsed_times)
sum_time = sum(elapsed_times)
avg_time = sum_time / num_calls
metrics = Metrics(sum_time, num_calls, min_time, max_time, avg_time, fname)
results.append(metrics)
total_time = sum([m.sum_time for m in results])
print("\t".join(["Percent", "Sum", "Calls", "Min", "Max", "Mean", "Function"]))
for m in sorted(results, reverse=True):
print("%.1f\t%.3f\t%d\t%.3f\t%.3f\t%.3f\t%s" % (100 * m.sum_time / total_time, m.sum_time, m.num_calls, m.min_time, m.max_time, m.avg_time, m.fname))
print("%.3f Total Time" % total_time)