Измерить время, прошедшее в Python? - PullRequest
918 голосов
/ 10 сентября 2011

Я хочу начать отсчет времени где-то в моем коде, а затем получить прошедшее время, чтобы измерить время, необходимое для выполнения нескольких функций. Я думаю, что неправильно использую модуль timeit, но документы меня просто сбивают с толку.

import timeit

start = timeit.timeit()
print "hello"
end = timeit.timeit()
print end - start

Ответы [ 26 ]

1152 голосов
/ 10 сентября 2011

Если вы просто хотите измерить истекшее время настенных часов между двумя точками, вы можете использовать time.time():

import time

start = time.time()
print("hello")
end = time.time()
print(end - start)

Это дает время выполнения в секундах.

Другой вариант, поскольку 3.3 может использовать perf_counter или process_time, в зависимости от ваших требований. До версии 3.3 было рекомендовано использовать time.clock (спасибо Amber ). Однако в настоящее время это устарело:

В Unix вернуть текущее время процессора в виде числа с плавающей запятой выражается в секундах. Точность, а на самом деле само определение значение «процессорное время», зависит от функции C с таким же именем.

В Windows эта функция возвращает часы настенных часов, прошедшие с момента первый вызов этой функции, как число с плавающей запятой, на основе Функция Win32 QueryPerformanceCounter(). Разрешение обычно лучше, чем одна микросекунда.

устарело с версии 3.3 : поведение этой функции зависит на платформе: используйте perf_counter() или process_time() вместо , в зависимости от ваших требований иметь четко определенное поведение.

497 голосов
/ 13 сентября 2014

Используйте timeit.default_timer вместо timeit.timeit. Первый предоставляет лучшие часы, доступные на вашей платформе и версии Python автоматически:

from timeit import default_timer as timer

start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282

timeit.default_timer присваивается time.time () или time.clock () в зависимости от ОС. На Python 3.3+ default_timer равен time.perf_counter () на всех платформах. См. Python - time.clock () против time.time () - точность?

Смотри также:

112 голосов
/ 30 января 2014

только Python 3:

Поскольку time.clock () устарело с Python 3.3 , вы можете использовать time.perf_counter() для общесистемной синхронизации или time.process_time() для синхронизации всего процесса, как вы привыкли использовать time.clock():

import time

t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t

Новая функция process_time не будет включать время, прошедшее во время сна.

77 голосов
/ 10 сентября 2011

Учитывая функцию, которую вы хотели бы рассчитать,

test.py:

def foo(): 
    # print "hello"   
    return "hello"

самый простой способ использовать timeit - вызвать его из командной строки:

% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop

Не пытайтесь использовать time.time или time.clock (наивно) для сравнения скорости функций. Они могут дать ошибочные результаты .

PS. Не помещайте операторы печати в функцию, которую вы хотите синхронизировать; в противном случае измеренное время будет зависеть от скорости терминала .

56 голосов
/ 04 мая 2015

Это интересно сделать с помощью менеджера контекста, который автоматически запоминает время начала при входе в блок with, а затем останавливает время окончания при выходе из блока. С небольшой хитростью вы можете даже получить подсчет прошедшего времени внутри блока из той же функции менеджера контекста.

В базовой библиотеке этого нет (но, вероятно, должно быть). Оказавшись на месте, вы можете делать такие вещи, как:

with elapsed_timer() as elapsed:
    # some lengthy code
    print( "midpoint at %.2f seconds" % elapsed() )  # time so far
    # other lengthy code

print( "all done at %.2f seconds" % elapsed() )

Вот код contextmanager , достаточный для выполнения этой задачи:

from contextlib import contextmanager
from timeit import default_timer

@contextmanager
def elapsed_timer():
    start = default_timer()
    elapser = lambda: default_timer() - start
    yield lambda: elapser()
    end = default_timer()
    elapser = lambda: end-start

И некоторый работающий демонстрационный код:

import time

with elapsed_timer() as elapsed:
    time.sleep(1)
    print(elapsed())
    time.sleep(2)
    print(elapsed())
    time.sleep(3)

Обратите внимание, что при разработке этой функции возвращаемое значение elapsed() замораживается при выходе из блока, и последующие вызовы возвращают ту же продолжительность (в этом примере игрушки около 6 секунд).

48 голосов
/ 14 августа 2017

Я предпочитаю это. timeit Документ слишком запутанный.

from datetime import datetime 

start_time = datetime.now() 

# INSERT YOUR CODE 

time_elapsed = datetime.now() - start_time 

print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))

Обратите внимание, что здесь нет никакого форматирования, я просто написал hh:mm:ss в распечатку, чтобы можно было интерпретировать time_elapsed

25 голосов
/ 10 сентября 2011

Использование time.time для измерения выполнения дает вам общее время выполнения ваших команд, включая время, затраченное другими процессами на вашем компьютере.Это время, которое пользователь замечает, но это не хорошо, если вы хотите сравнить различные фрагменты кода / алгоритмы / функции / ...

Подробнее о timeit:

Если вы хотите глубже понять профилирование:

Обновление :Я много использовал http://pythonhosted.org/line_profiler/ в течение прошлого года и считаю его очень полезным и рекомендую использовать его вместо модуля профиля Pythons.

18 голосов
/ 04 февраля 2016

Вот небольшой класс таймера, который возвращает строку «чч: мм: сс»:

class Timer:
  def __init__(self):
    self.start = time.time()

  def restart(self):
    self.start = time.time()

  def get_time_hhmmss(self):
    end = time.time()
    m, s = divmod(end - self.start, 60)
    h, m = divmod(m, 60)
    time_str = "%02d:%02d:%02d" % (h, m, s)
    return time_str

Использование:

# Start timer
my_timer = Timer()

# ... do something

# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )

# ... use the timer again
my_timer.restart()

# ... do something

# Get time:
time_hhmmss = my_timer.get_time_hhmmss()

# ... etc
17 голосов
/ 27 декабря 2013

Модули python cProfile и pstats предлагают отличную поддержку для измерения времени, затраченного на выполнение определенных функций, без необходимости добавления какого-либо кода вокруг существующих функций.

Например, если у вас есть скрипт на python timeFunctions.py:

import time

def hello():
    print "Hello :)"
    time.sleep(0.1)

def thankyou():
    print "Thank you!"
    time.sleep(0.05)

for idx in range(10):
    hello()

for idx in range(100):
    thankyou()

Чтобы запустить профилировщик и сгенерировать статистику для файла, вы можете просто запустить:

python -m cProfile -o timeStats.profile timeFunctions.py

Для этого используется модуль cProfile для профилирования всех функций в timeFunctions.py и сбора статистики в файле timeStats.profile. Обратите внимание, что нам не нужно было добавлять какой-либо код в существующий модуль (timeFunctions.py), и это можно сделать с любым модулем.

Получив файл статистики, вы можете запустить модуль pstats следующим образом:

python -m pstats timeStats.profile

Это запускает интерактивный браузер статистики, который дает вам много приятных функций. Для вашего конкретного случая использования вы можете просто проверить статистику вашей функции. В нашем примере проверка статистики для обеих функций показывает нам следующее:

Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'hello'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10    0.000    0.000    1.001    0.100 timeFunctions.py:3(hello)

timeStats.profile% stats thankyou
<timestamp>    timeStats.profile

         224 function calls in 6.014 seconds

   Random listing order was used
   List reduced from 6 to 1 due to restriction <'thankyou'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      100    0.002    0.000    5.012    0.050 timeFunctions.py:7(thankyou)

Пример с пустышкой мало что дает, но дает представление о том, что можно сделать. Лучшая часть этого подхода заключается в том, что мне не нужно редактировать существующий код, чтобы получить эти цифры и, очевидно, помочь с профилированием.

17 голосов
/ 31 декабря 2016

Вот еще один контекстный менеджер для временного кода -

Использование:

from benchmark import benchmark

with benchmark("Test 1+1"):
    1+1
=>
Test 1+1 : 1.41e-06 seconds

или, если вам нужно значение времени

with benchmark("Test 1+1") as b:
    1+1
print(b.time)
=>
Test 1+1 : 7.05e-07 seconds
7.05233786763e-07

, эталонный тест.py :

from timeit import default_timer as timer

class benchmark(object):

    def __init__(self, msg, fmt="%0.3g"):
        self.msg = msg
        self.fmt = fmt

    def __enter__(self):
        self.start = timer()
        return self

    def __exit__(self, *args):
        t = timer() - self.start
        print(("%s : " + self.fmt + " seconds") % (self.msg, t))
        self.time = t

Адаптировано с http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.html

...