Ответ 1
Сделайте это вызываемым:
if __name__=='__main__':
from timeit import Timer
t = Timer(lambda: superMegaIntenseFunction(10))
print(t.timeit(number=1))
Должно сработать
Я борюсь с этим с помощью timeit и задавался вопросом, есть ли у кого-нибудь советы.
В принципе у меня есть функция (которую я передаю значение), которую я хочу проверить скорость и создал это:
if __name__=='__main__':
from timeit import Timer
t = Timer(superMegaIntenseFunction(10))
print t.timeit(number=1)
но когда я запускаю его, я получаю странные ошибки, например, исходящие из модуля timeit.:
ValueError: stmt is neither a string nor callable
Если я запускаю функцию самостоятельно, она работает нормально. Его когда я обертываю его во время его модуля, я получаю ошибки (я пытался использовать двойные кавычки и без..samoutput).
любые предложения были бы замечательными!
Спасибо!
Сделайте это вызываемым:
if __name__=='__main__':
from timeit import Timer
t = Timer(lambda: superMegaIntenseFunction(10))
print(t.timeit(number=1))
Должно сработать
Timer(superMegaIntenseFunction(10))
означает "вызов superMegaIntenseFunction(10)
, а затем передать результат в Timer
". Это явно не то, что вы хотите. Timer
ожидает либо вызываемого (как он звучит: что-то, что можно назвать, например, функции), либо строки (чтобы он мог интерпретировать содержимое строки как код Python). Timer
работает, неоднократно вызывая вызывающую вещь и видя, сколько времени занимает.
Timer(superMegaIntenseFunction)
будет проходить проверку типа, потому что superMegaIntenseFunction
является вызываемым. Однако Timer
не знает, какие значения передаются на superMegaIntenseFunction
.
Простым способом, конечно же, является использование строки с кодом. Нам нужно передать аргумент "setup" в код, потому что строка "интерпретируется как код" в новом контексте - у нее нет доступа к тому же globals
, поэтому вам нужно запустить еще один бит кода, чтобы сделайте определение доступным - см. ответ @oxtopus.
С lambda
(как в ответе @Pablo), мы можем привязать параметр 10
к вызову superMegaIntenseFunction
. Все, что мы делаем, это создание другой функции, которая не принимает аргументов и вызывает superMegaIntenseFunction
с помощью 10
. Это как если бы вы использовали def
для создания другой такой функции, за исключением того, что новая функция не получает имя (потому что оно не нуждается в нем).
Вам нужно передать строку. то есть.
t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')
Заметка для будущих посетителей. Если вам нужно заставить его работать в отладчике pdb
, а superMegaIntenseFunction
не находится в глобальной области, вы можете заставить его работать, добавив в globals
:
globals()['superMegaIntenseFunction'] = superMegaIntenseFunction
timeit.timeit(lambda: superMegaIntenseFunction(x))
Обратите внимание, что временные накладные расходы немного больше в этом случае из-за дополнительных вызовов функций. [источник]
Один из способов сделать это - использовать частичный, чтобы функция "superMegaIntenseFunction" использовалась как вызываемая (т.е. Без()) в таймере или непосредственно внутри timeit.timeit. Использование partial передаст аргумент функции, когда он будет вызываться таймером.
from functools import partial
from timeit import timeit
print(timeit(partial(superMegaIntenseFunction, 10), number=1))