Если вы действительно хотите прямой эквивалент, просто позвоните tic = time.time()и toc = time.time(), то , print toc-tic, 'sec Elapsed'как люди говорили ниже, однако, timeitявляется более надежным.
Джо Кингтон
Похоже, я получаю лучшие результаты, используя подход @JoeKington в сочетании с timeit.default_timer (), например так:, tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()then print toc-tic.
littleO
1
Библиотека pytictoc кажется наиболее подходящей, синтаксис даже немного лучше, чем ttictoc ниже. pypi.org/project/pytictoc
FlorianH
Ответы:
174
Помимо timeitупомянутого ThiefMaster, простой способ сделать это (после импорта time):
t = time.time()# do stuff
elapsed = time.time()- t
У меня есть вспомогательный класс, который я люблю использовать:
@eat: Я с уважением не согласен. Люди всегда использовали команду unix timeдля измерения времени выполнения программ, и этот метод воспроизводит это внутри кода Python. Я не вижу в этом ничего плохого, если это правильный инструмент для работы. timeitне всегда так, и профилировщик - гораздо более тяжелое решение для большинства нужд
Эли Бендерски
4
Я бы предложил последнюю строчку print 'Elapsed: %.2f seconds % (time.time() - self.tstart)'. Трудно понять без% .2f. Спасибо за отличную идею.
Джан Каваклыоглу
4
На первый взгляд это выглядит очень удобным, но на практике требуется, чтобы кто-то сделал отступ в кодовом блоке, который нужно рассчитать, что может быть довольно неудобным в зависимости от длины кодового блока и выбранного редактора. По-прежнему элегантное решение, которое корректно ведет себя в случае вложенного использования.
Стефан
1
Я думаю ты хочешь elapsed = t - time.time(), а не elapsed = time.time() - t. В последнем истекший будет отрицательным. Я предложил это изменение как правку.
rysqui
3
@rysqui - Разве текущее время не всегда больше, чем в предыдущий раз ? Я думаю, что elapsed = time.time() - tэто форма, которая всегда дает положительное значение.
Скотт Смит
32
У меня был такой же вопрос, когда я перешел на Python с Matlab. С помощью этой ветки я смог построить точный аналог Matlab tic()и toc()functions. Просто вставьте следующий код в начало вашего скрипта.
import time
defTicTocGenerator():# Generator that returns time differences
ti =0# initial time
tf = time.time()# final timewhileTrue:
ti = tf
tf = time.time()yield tf-ti # returns the time differenceTicToc=TicTocGenerator()# create an instance of the TicTocGen generator# This will be the main function through which we define both tic() and toc()def toc(tempBool=True):# Prints the time difference yielded by generator instance TicToc
tempTimeInterval =next(TicToc)if tempBool:print("Elapsed time: %f seconds.\n"%tempTimeInterval )def tic():# Records a time in TicToc, marks the beginning of a time interval
toc(False)
Это оно! Теперь мы готовы в полной мере использовать tic()и toc()так же , как в Matlab. Например
Собственно, это более универсально, чем встроенные функции Matlab. Здесь вы можете создать еще один экземпляр TicTocGeneratorдля отслеживания нескольких операций или просто для другого времени. Например, при хронометрировании скрипта теперь мы можем синхронизировать каждый фрагмент скрипта отдельно, а также весь скрипт. (Приведу конкретный пример)
TicToc2=TicTocGenerator()# create another instance of the TicTocGen generatordef toc2(tempBool=True):# Prints the time difference yielded by generator instance TicToc2
tempTimeInterval =next(TicToc2)if tempBool:print("Elapsed time 2: %f seconds.\n"%tempTimeInterval )def tic2():# Records a time in TicToc2, marks the beginning of a time interval
toc2(False)
Теперь у вас должна быть возможность синхронизировать две отдельные вещи: В следующем примере мы синхронизируем весь сценарий и части сценария отдельно.
Лучшим аналогом tic и toc было бы просто определить их в python.
def tic():#Homemade version of matlab tic and toc functionsimport time
global startTime_for_tictoc
startTime_for_tictoc = time.time()def toc():import time
if'startTime_for_tictoc'in globals():print"Elapsed time is "+ str(time.time()- startTime_for_tictoc)+" seconds."else:print"Toc: start time not set"
Это не будет работать правильно в случае вложенного использования ticи toc, которое поддерживает Matlab. Потребуется немного больше изощренности.
Стефан
2
Я реализовал аналогичные функции в своем собственном коде, когда мне нужно было немного времени. Однако я бы удалил import timeвнешнюю часть обеих функций, поскольку это может занять некоторое время.
Bas Swinckels
Если вы настаиваете на использовании этой техники и вам нужно, чтобы она обрабатывала вложенные tic / toc, сделайте глобальный список и позвольте ticpush к нему и выталкивать tocиз него.
Ахмед Фасих
1
Также я читал в другом месте, что timeit.default_timer()лучше, чем time.time()потому, что time.clock()может быть более подходящим в зависимости от ОС
Мигель
@AhmedFasih Это мой ответ, хотя можно было бы улучшить и другие вещи.
antonimmo
15
Обычно IPython - х %time, %timeit, %prunи %lprun(если таковой line_profilerустановлен) удовлетворяет мои потребности профилирующие достаточно хорошо. Однако вариант использования tic-toc-подобной функциональности возник, когда я попытался профилировать вычисления, которые выполнялись интерактивно, то есть движением мыши пользователя в графическом интерфейсе. Я чувствовал , как спам tics и tocS в источниках во время тестирования в интерактивном режиме будет самым быстрым способом выявить узкие места. Я пошел с Timerклассом Эли Бендерски , но не был полностью доволен, так как мне потребовалось изменить отступы моего кода, что может быть неудобно в некоторых редакторах и сбивать с толку систему контроля версий. Более того, может возникнуть необходимость в измерении времени между точками в разных функциях, что не будет работать сwithзаявление. Попробовав много хитрости Python, я нашел простое решение, которое работает лучше всего:
from time import time
_tstart_stack =[]def tic():
_tstart_stack.append(time())def toc(fmt="Elapsed: %s s"):print fmt %(time()- _tstart_stack.pop())
Поскольку это работает, помещая время начала в стек, он будет работать правильно для нескольких уровней tics и tocs. Это также позволяет изменить строку формата tocоператора для отображения дополнительной информации, которая мне понравилась в Timerклассе Эли .
По какой-то причине меня беспокоили накладные расходы на чистую реализацию Python, поэтому я также протестировал модуль расширения C:
Это для MacOSX, и я пропустил код, чтобы проверить, lvlвыходит ли он за рамки для краткости. Хотя tictoc.res()в моей системе это дает разрешение около 50 наносекунд, я обнаружил, что дрожание при измерении любого оператора Python легко находится в диапазоне микросекунд (и намного больше при использовании из IPython). На этом этапе накладные расходы на реализацию Python становятся незначительными, поэтому ее можно использовать с той же уверенностью, что и реализация C.
Я обнаружил, что полезность tic-toc-подхода практически ограничена блоками кода, выполнение которых занимает более 10 микросекунд. Ниже этого уровня timeitтребуются стратегии усреднения, подобные приведенному выше, для получения точных измерений.
Я только что создал модуль [tictoc.py] для создания вложенных тик-тактов, что и делает Matlab.
from time import time
tics =[]def tic():
tics.append(time())def toc():if len(tics)==0:returnNoneelse:return time()-tics.pop()
А работает это так:
from tictoc import tic, toc
# This keeps track of the whole process
tic()# Timing a small portion of code (maybe a loop)
tic()# -- Nested code here --# End
toc()# This returns the elapse time (in seconds) since the last invocation of tic()
toc()# This does the same for the first tic()
Я должен предупредить вас, что при одновременном использовании более чем 1 модулем это может вести себя не так, как нужно, поскольку модули (AFAIK) ведут себя как одиночные.
antonimmo
3
Взгляните на timeitмодуль. Это не совсем эквивалентно, но если код, который вы хотите разложить, находится внутри функции, вы можете легко его использовать.
Это также можно сделать с помощью обертки. Очень общий способ отсчета времени.
Обертка в этом примере кода обертывает любую функцию и выводит количество времени, необходимое для выполнения функции:
def timethis(f):import time
def wrapped(*args,**kwargs):
start = time.time()
r = f(*args,**kwargs)print"Executing {0} took {1} seconds".format(f.func_name, time.time()-start)return r
return wrapped
@timethisdef thistakestime():for x in range(10000000):pass
thistakestime()
Функция-оболочка timethis называется декоратором. Немного более подробное объяснение здесь: medium.com/pythonhive/…
Мирча
1
Я немного изменил ответ @Eli __init__()Bendersky, чтобы использовать ctor и dtor __del__()для определения времени, чтобы его можно было использовать более удобно, не отступая от исходного кода:
Чтобы использовать, просто поместите Timer ("blahblah") в начало некоторой локальной области видимости. Истекшее время будет напечатано в конце области:
for i in xrange(5):
timer =Timer("eigh()")
x = numpy.random.random((4000,4000));
x =(x+x.T)/2
numpy.linalg.eigh(x)print i+1
timer =None
Проблема с этой реализацией заключается в том, что timerона не удаляется после последнего вызова, если после forцикла следует какой-либо другой код . Чтобы получить последнее значение таймера, нужно удалить или перезаписать timerпосле forцикла, например через timer = None.
bastelflp 05
1
@bastelflp Только что понял, что я неправильно понял, что вы имели в виду ... Теперь ваше предложение включено в код. Спасибо.
Как и у Эли, его можно использовать как диспетчер контекста:
import time
withTimer('Count'):for i in range(0,10_000_000):pass
Вывод:
[Count]Elapsed:0.27 seconds
Я также обновил его, чтобы распечатать единицы времени (секунды) и сократить количество цифр, как было предложено Can, а также с возможностью добавления в файл журнала. Вы должны импортировать datetime, чтобы использовать функцию ведения журнала:
import time
import datetime
withTimer('Count','log.txt'):for i in range(0,10_000_000):pass
вы можете просто использовать tic(), toc()и вкладывать их как в Matlab
в качестве альтернативы, вы можете назвать их: tic(1), toc(1)или tic('very-important-block'), toc('very-important-block')и таймеры с разными названиями не будут мешать
их импорт таким образом предотвращает взаимодействие между модулями, использующими его.
(здесь toc не выводит истекшее время, а возвращает его.)
tic = time.time()
иtoc = time.time()
, то ,print toc-tic, 'sec Elapsed'
как люди говорили ниже, однако,timeit
является более надежным.tic = timeit.default_timer(); (U,S,V) = np.linalg.svd(A); toc = timeit.default_timer()
thenprint toc-tic
.Ответы:
Помимо
timeit
упомянутого ThiefMaster, простой способ сделать это (после импортаtime
):У меня есть вспомогательный класс, который я люблю использовать:
Его можно использовать как менеджер контекста:
Иногда я нахожу этот метод более удобным, чем
timeit
- все зависит от того, что вы хотите измерить.источник
time
для измерения времени выполнения программ, и этот метод воспроизводит это внутри кода Python. Я не вижу в этом ничего плохого, если это правильный инструмент для работы.timeit
не всегда так, и профилировщик - гораздо более тяжелое решение для большинства нуждprint 'Elapsed: %.2f seconds % (time.time() - self.tstart)'
. Трудно понять без% .2f. Спасибо за отличную идею.elapsed = t - time.time()
, а неelapsed = time.time() - t
. В последнем истекший будет отрицательным. Я предложил это изменение как правку.elapsed = time.time() - t
это форма, которая всегда дает положительное значение.У меня был такой же вопрос, когда я перешел на Python с Matlab. С помощью этой ветки я смог построить точный аналог Matlab
tic()
иtoc()
functions. Просто вставьте следующий код в начало вашего скрипта.Это оно! Теперь мы готовы в полной мере использовать
tic()
иtoc()
так же , как в Matlab. НапримерСобственно, это более универсально, чем встроенные функции Matlab. Здесь вы можете создать еще один экземпляр
TicTocGenerator
для отслеживания нескольких операций или просто для другого времени. Например, при хронометрировании скрипта теперь мы можем синхронизировать каждый фрагмент скрипта отдельно, а также весь скрипт. (Приведу конкретный пример)Теперь у вас должна быть возможность синхронизировать две отдельные вещи: В следующем примере мы синхронизируем весь сценарий и части сценария отдельно.
Собственно, вам даже не нужно
tic()
каждый раз пользоваться. Если у вас есть серия команд, которые вы хотите отсрочить, вы можете написатьЯ надеюсь, что это поможет.
источник
Лучшим аналогом tic и toc было бы просто определить их в python.
Затем вы можете использовать их как:
источник
tic
иtoc
, которое поддерживает Matlab. Потребуется немного больше изощренности.import time
внешнюю часть обеих функций, поскольку это может занять некоторое время.tic
push к нему и выталкиватьtoc
из него.timeit.default_timer()
лучше, чемtime.time()
потому, чтоtime.clock()
может быть более подходящим в зависимости от ОСОбычно IPython - х
%time
,%timeit
,%prun
и%lprun
(если таковойline_profiler
установлен) удовлетворяет мои потребности профилирующие достаточно хорошо. Однако вариант использованияtic-toc
-подобной функциональности возник, когда я попытался профилировать вычисления, которые выполнялись интерактивно, то есть движением мыши пользователя в графическом интерфейсе. Я чувствовал , как спамtic
s иtoc
S в источниках во время тестирования в интерактивном режиме будет самым быстрым способом выявить узкие места. Я пошел сTimer
классом Эли Бендерски , но не был полностью доволен, так как мне потребовалось изменить отступы моего кода, что может быть неудобно в некоторых редакторах и сбивать с толку систему контроля версий. Более того, может возникнуть необходимость в измерении времени между точками в разных функциях, что не будет работать сwith
заявление. Попробовав много хитрости Python, я нашел простое решение, которое работает лучше всего:Поскольку это работает, помещая время начала в стек, он будет работать правильно для нескольких уровней
tic
s иtoc
s. Это также позволяет изменить строку форматаtoc
оператора для отображения дополнительной информации, которая мне понравилась вTimer
классе Эли .По какой-то причине меня беспокоили накладные расходы на чистую реализацию Python, поэтому я также протестировал модуль расширения C:
Это для MacOSX, и я пропустил код, чтобы проверить,
lvl
выходит ли он за рамки для краткости. Хотяtictoc.res()
в моей системе это дает разрешение около 50 наносекунд, я обнаружил, что дрожание при измерении любого оператора Python легко находится в диапазоне микросекунд (и намного больше при использовании из IPython). На этом этапе накладные расходы на реализацию Python становятся незначительными, поэтому ее можно использовать с той же уверенностью, что и реализация C.Я обнаружил, что полезность
tic-toc
-подхода практически ограничена блоками кода, выполнение которых занимает более 10 микросекунд. Ниже этого уровняtimeit
требуются стратегии усреднения, подобные приведенному выше, для получения точных измерений.источник
Можно использовать
tic
иtoc
отttictoc
. Установите его с помощьюИ просто импортируйте их в свой скрипт, как показано ниже
источник
Я только что создал модуль [tictoc.py] для создания вложенных тик-тактов, что и делает Matlab.
А работает это так:
Я надеюсь, что это помогает.
источник
Взгляните на
timeit
модуль. Это не совсем эквивалентно, но если код, который вы хотите разложить, находится внутри функции, вы можете легко его использовать.источник
timeit
лучше всего подходит для тестов. Это даже не обязательно должна быть одна функция, вы можете передавать чрезвычайно сложные операторы.В коде:
Отказ от ответственности: я являюсь автором этой библиотеки.
источник
Это также можно сделать с помощью обертки. Очень общий способ отсчета времени.
Обертка в этом примере кода обертывает любую функцию и выводит количество времени, необходимое для выполнения функции:
источник
Я немного изменил ответ @Eli
__init__()
Bendersky, чтобы использовать ctor и dtor__del__()
для определения времени, чтобы его можно было использовать более удобно, не отступая от исходного кода:Чтобы использовать, просто поместите Timer ("blahblah") в начало некоторой локальной области видимости. Истекшее время будет напечатано в конце области:
Он распечатывает:
источник
timer
она не удаляется после последнего вызова, если послеfor
цикла следует какой-либо другой код . Чтобы получить последнее значение таймера, нужно удалить или перезаписатьtimer
послеfor
цикла, например черезtimer = None
.Обновление ответа Эли на Python 3:
Как и у Эли, его можно использовать как диспетчер контекста:
Вывод:
Я также обновил его, чтобы распечатать единицы времени (секунды) и сократить количество цифр, как было предложено Can, а также с возможностью добавления в файл журнала. Вы должны импортировать datetime, чтобы использовать функцию ведения журнала:
источник
Основываясь на ответах Стефана и Антониммо, я закончил тем, что
в
utils.py
модуле, и я использую его сСюда
tic()
,toc()
и вкладывать их как в Matlabtic(1)
,toc(1)
илиtic('very-important-block')
,toc('very-important-block')
и таймеры с разными названиями не будут мешать(здесь toc не выводит истекшее время, а возвращает его.)
источник