it-swarm.com.ru

Измерить время, прошедшее в Python?

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

import timeit

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

Если вы просто хотите измерить прошедшее время между двумя точками, вы можете использовать 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() вместо, в зависимости от ваших требований иметь четко определенное поведение.

1012
NPE

Используйте 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 () - точность?

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

420
jfs

Только 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 не будет включать время, прошедшее во время сна.

99
Pierre Prinetti

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

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. Не помещайте операторы печати в функцию, которую вы хотите синхронизировать; в противном случае измеренное время будет зависеть от скорости терминала .

73
unutbu

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

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

45
user1761806

Это интересно сделать с помощью менеджера контекста, который автоматически запоминает время начала при входе в блок 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 code, достаточный для выполнения этой задачи:

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 секунд). 

43
gojomo

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

Больше информации о timeit:

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

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

24
rocksportrocker

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

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
18
Danijel

Модули 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

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

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)

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

16
sanchitarora

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

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

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

benchmark.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

16
Brian Burns

Используйте модуль профилировщика. Это дает очень подробный профиль.

import profile
profile.run('main()')

это выводит что-то вроде:

          5 function calls in 0.047 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :0(exec)
        1    0.047    0.047    0.047    0.047 :0(setprofile)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        0    0.000             0.000          profile:0(profiler)
        1    0.000    0.000    0.047    0.047 profile:0(main())
        1    0.000    0.000    0.000    0.000 two_sum.py:2(twoSum)

Я нашел это очень информативным.

14
Leonid Ganeline

(Только для Ipython) вы можете использовать % timeit для измерения среднего времени обработки:

def foo():
    print "hello"

а потом: 

%timeit foo()

результат примерно такой:

10000 loops, best of 3: 27 µs per loop
12
Eyal Ch

на python3:

from time import sleep, perf_counter as pc
t0 = pc()
sleep(1)
print(pc()-t0)

элегантный и короткий.

9
DmitrySemenov

Вид супер позднего ответа, но, возможно, это кому-то помогает. Это способ сделать это, который я считаю очень чистым.

import time

def timed(fun, *args):
    s = time.time()
    r = fun(*args)
    print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
    return(r)

timed(print, "Hello")

Имейте в виду, что «печать» - это функция в Python 3, а не Python 2.7. Тем не менее, он работает с любой другой функцией. Ура!

9
Andreas Herman

Мы также можем преобразовать время в удобочитаемое время.

import time, datetime

start = time.clock()

def num_multi1(max):
    result = 0
    for num in range(0, 1000):
        if (num % 3 == 0 or num % 5 == 0):
            result += num

    print "Sum is %d " % result

num_multi1(1000)

end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')
6
Kamlesh Verma

Вот мои выводы, пройдя здесь много хороших ответов, а также несколько других статей.

Во-первых, вы всегда хотите использовать timeit, а не time.time (и во многих случаях API счетчика перфорирования), потому что 

  1. timeit выбирает лучший таймер, доступный в вашей версии ОС и Python. 
  2. timeit отключает сборку мусора, однако это не то, что вы можете или не можете хотеть.

Теперь проблема в том, что использовать его не так просто, потому что он нуждается в настройке и все становится ужасно, когда у вас есть куча импортов. В идеале вы просто хотите декоратор или использовать блок with и измерять время. К сожалению, для этого нет ничего встроенного, поэтому я создал ниже небольшой служебный модуль.

Служебный модуль Timing

# utils.py
from functools import wraps
import gc
import timeit

def MeasureTime(f):
    @wraps(f)
    def _wrapper(*args, **kwargs):
        gcold = gc.isenabled()
        gc.disable()
        start_time = timeit.default_timer()
        try:
            result = f(*args, **kwargs)
        finally:
            elapsed = timeit.default_timer() - start_time
            if gcold:
                gc.enable()
            print('Function "{}": {}s'.format(f.__name__, elapsed))
        return result
    return _wrapper

class MeasureBlockTime:
    def __init__(self,name="(block)", no_print = False, disable_gc = True):
        self.name = name
        self.no_print = no_print
        self.disable_gc = disable_gc
    def __enter__(self):
        if self.disable_gc:
            self.gcold = gc.isenabled()
            gc.disable()
        self.start_time = timeit.default_timer()
    def __exit__(self,ty,val,tb):
        self.elapsed = timeit.default_timer() - self.start_time
        if self.disable_gc and self.gcold:
            gc.enable()
        if not self.no_print:
            print('Function "{}": {}s'.format(self.name, self.elapsed))
        return False #re-raise any exceptions

Как рассчитать функции

Теперь вы можете определить время любой функции, просто поставив перед ней декоратор:

import utils

@utils.MeasureTime
def MyBigFunc():
    #do something time consuming
    for i in range(10000):
        print(i)

Как блокировать временной код

Если вы хотите синхронизировать часть кода, просто поместите ее в блок with:

import utils

#somewhere in my code

with utils.MeasureBlockTime("MyBlock"):
    #do something time consuming
    for i in range(10000):
        print(i)

# rest of my code

Преимущества

Есть несколько полуобеспеченных версий, поэтому я хочу отметить несколько основных моментов:

  1. Используйте таймер из timeit вместо time.time по причинам, описанным ранее.
  2. Отключить GC во время синхронизации.
  3. Декоратор принимает функции с именованными или безымянными параметрами.
  4. Возможность отключить печать во время блока (используйте with utils.MeasureBlockTime() as t, а затем t.elapsed).
  5. Возможность держать gc включенным для синхронизации блока.
6
Shital Shah

Еще один способ использовать timeit :

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)
6
raacer

Я сделал библиотеку для этого, если вы хотите измерить функцию, вы можете просто сделать это так 


from pythonbenchmark import compare, measure
import time

a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]

@measure
def myFunction(something):
    time.sleep(0.4)

@measure
def myOptimizedFunction(something):
    time.sleep(0.2)

myFunction(input)
myOptimizedFunction(input)

https://github.com/Karlheinzniebuhr/pythonbenchmark

5
karlpy

Вы можете использовать время.

Вот пример того, как проверить naive_func, который принимает параметр, используя Python REPL:

>>> import timeit                                                                                         

>>> def naive_func(x):                                                                                    
...     a = 0                                                                                             
...     for i in range(a):                                                                                
...         a += i                                                                                        
...     return a                                                                                          

>>> def wrapper(func, *args, **kwargs):                                                                   
...     def wrapper():                                                                                    
...         return func(*args, **kwargs)                                                                  
...     return wrapper                                                                                    

>>> wrapped = wrapper(naive_func, 1_000)                                                                  

>>> timeit.timeit(wrapped, number=1_000_000)                                                              
0.4458435332577161  

Вам не нужна функция-обертка, если у функции нет никаких параметров. 

4
Vlad Bezden

Время измерения в секундах:

from timeit import default_timer as timer
from datetime import timedelta

start = timer()
end = timer()
print(timedelta(seconds=end-start))
1
Gal Bracha

Единственный способ, которым я могу думать, это использовать time.time().

import time
start = time.time()
sleep(5) #just to give it some delay to show it working
finish = time.time()
elapsed = finish - start
print(elapsed)

Надеюсь, что это поможет.

0
Trooper Z