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

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

import timeit

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

Ответы [ 26 ]

16 голосов
/ 19 марта 2019

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

from timeit import default_timer as timer
from datetime import timedelta

start = timer()
end = timer()
print(timedelta(seconds=end-start))

выход

0:00:01.946339
15 голосов
/ 19 июля 2017

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

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)

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

13 голосов
/ 12 сентября 2018

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

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

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

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

Модуль утилит синхронизации

# 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 включенным для синхронизации блока.
12 голосов
/ 24 ноября 2014

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

def foo():
    print "hello"

, а затем:

%timeit foo()

результат - что-токак:

10000 loops, best of 3: 27 µs per loop
11 голосов
/ 15 января 2016

на python3:

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

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

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

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

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.Тем не менее, он работает с любой другой функцией.Ура! * * 1004

8 голосов
/ 15 декабря 2016

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

from timeit import timeit

def func():
    return 1 + 1

time = timeit(func, number=1)
print(time)
7 голосов
/ 17 сентября 2016

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

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 голосов
/ 04 мая 2015

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


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

4 голосов
/ 18 июня 2019

Мне нравится Простой (Python 3):

from timeit import timeit

timeit(lambda: print("hello"))

Выход составляет микросекунд для одного исполнения:

2.430883963010274

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


Для медленных операций добавляют меньшее значение число итераций или вы могли бы ждать вечно:

import time

timeit(lambda: time.sleep(1.5), number=1)

Выход всегда находится в секундах для общего числа число итераций:

1.5015795179999714
...