Как можно выполнить блок случайного кода в python не прибегая к его строковому оформлению. Я, скорее всего, нет заинтересован в использовании оценка или исполнитель .
Таким образом, вариант использования будет заключаться в обеспечении синхронизации блока кода, но не требует взлома для первого преобразования блока кода в строку:
def formatTimeDelta(td):
return '%d.%d' %(td.total_seconds() , int(td.microseconds/1000))
def timeit(tag, block):
def getNow(): return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
startt = datetime.datetime.now()
print('Starting %s at %s..' %(tag,getNow()))
block # Execute the code!
duration = formatTimeDelta(datetime.datetime.now() - startt)
print('Completed %s at %s with duration=%s secs' %(tag,getNow(), duration))
Тогда мы будем использовать что-то вроде:
Учитывая «случайный» кодовый блок
def waitsecs(nsecs):
import time
time.sleep(nsecs)
print('I slept %d secs..' %nsecs)
timeit('wait five secs', (
waitsecs(5)
))
Я считаю, что делал все это в прошлом, но, похоже, не могу выкопать это ..
В примере, который я вижу, используются строки .. timeit.Timer('for i in xrange(10): oct(i)', 'gc.enable()').timeit()
. Если вы видите использование с Timer
, которое использует код настоящий, укажите это.
timeit.Timer
также принимает callable, см. мой пример
ах, хорошо, я вижу в исходном коде аргумент может быть либо строкой, либо вызываемым. Пожалуйста, ответьте
Используйте декоратор, например: @timeit декоратор:
def timeit(method):
def timed(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
if 'log_time' in kw:
name = kw.get('log_name', method.__name__.upper())
kw['log_time'][name] = int((te - ts) * 1000)
else:
print '%r %2.2f ms' % \
(method.__name__, (te - ts) * 1000)
return result
return timed
Добавление декоратора к методу:
@timeit
def get_all_employee_details(**kwargs):
print 'employee details'
Взято из: https://medium.com/pythonhive/python-decorator-to-measure-the-execution-time-of-methods-fa04cb6bb36d
timeit.Timer
делает именно это.
from time import sleep
from timeit import Timer
print(Timer(lambda: sleep(5)).repeat(1, 1))
# [5.000540999999999]
repeat
— это всего лишь один из способов рассчитать время функции, прочтите связанные документы, чтобы узнать о других доступных методах.
Я пытался понять из исходного кода timeit.py
, как обрабатываются Callable
, но не «понял». Если бы вы смогли пролить немного света, это было бы бонусом.
The stmt and setup parameters can also take objects that are callable without arguments
Я, наверное, прочитал это один раз (или два, ...) и сразу забыл.
@javadba timeit.Timer.__init__
делает очень явную проверку: elif callable(stmt):
Да, я это видел, но я пытаюсь углубиться и понять, как на самом деле вызывается блок кода stmt
/. Это не должно быть eval
или exec
.. так каков механизм?
Вы можете отправить callable в функцию timeit.timeit()
, но Только, если у нее нет атрибутов. Если у него есть какие-либо атрибуты, вы должны использовать код установки.
timeit.timeit()
функция имеет атрибут настройки. Вы можете отправить код (но все еще строковый) для его «оценки» до того, как timeit
Timer
объект начнет работать. Вот пример:
import timeit
s = """
import math
def waka(number):
return math.sqrt(number)
"""
timeit.timeit('waka(100)', setup=s)
Вот как работает timeit.timeit()
:
Create a Timer instance with the given statement, setup code and timer function and run its timeit() method with number executions. The optional globals argument specifies a namespace in which to execute the code.
Суть вопроса заключалась в том, чтобы не использовать строки для синхронизируемого кода.
Самый простой способ, который я нашел, — это использовать магическая команда%timeit
в блокноте ipython или Jupyter. Вы можете указать количество повторений и петель, если хотите:
$ ipython
In [1]: import time
In [2]: %timeit -n1 -r1 time.sleep(5)
5 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
In [3]: %timeit [i**2 for i in range(10000)]
8.12 ms ± 14.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Вам не нужна никакая лямбда, какая-либо определенная функция или какой-либо строковый код.
Спасибо - я в основном отошел от блокнотов, за исключением целей демонстрации, и делаю тяжелую работу в pycharm
. В любом случае будет голосование, поскольку оно отвечает на вопрос об оболочке ноутбука.
Я могу что-то упустить, но это очень похоже на то, для чего предназначен
timeit.Timer
. Напримерprint(timeit.Timer(func_to_time).repeat(1, 1))