Подтвердить что ты не робот

Как использовать python timeit при передаче переменных в функции?

Я борюсь с этим с помощью 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).

любые предложения были бы замечательными!

Спасибо!

4b9b3361

Ответ 1

Сделайте это вызываемым:

if __name__=='__main__':
    from timeit import Timer
    t = Timer(lambda: superMegaIntenseFunction(10))
    print(t.timeit(number=1))

Должно сработать

Ответ 2

Timer(superMegaIntenseFunction(10)) означает "вызов superMegaIntenseFunction(10), а затем передать результат в Timer". Это явно не то, что вы хотите. Timer ожидает либо вызываемого (как он звучит: что-то, что можно назвать, например, функции), либо строки (чтобы он мог интерпретировать содержимое строки как код Python). Timer работает, неоднократно вызывая вызывающую вещь и видя, сколько времени занимает.

Timer(superMegaIntenseFunction) будет проходить проверку типа, потому что superMegaIntenseFunction является вызываемым. Однако Timer не знает, какие значения передаются на superMegaIntenseFunction.

Простым способом, конечно же, является использование строки с кодом. Нам нужно передать аргумент "setup" в код, потому что строка "интерпретируется как код" в новом контексте - у нее нет доступа к тому же globals, поэтому вам нужно запустить еще один бит кода, чтобы сделайте определение доступным - см. ответ @oxtopus.

С lambda (как в ответе @Pablo), мы можем привязать параметр 10 к вызову superMegaIntenseFunction. Все, что мы делаем, это создание другой функции, которая не принимает аргументов и вызывает superMegaIntenseFunction с помощью 10. Это как если бы вы использовали def для создания другой такой функции, за исключением того, что новая функция не получает имя (потому что оно не нуждается в нем).

Ответ 3

Вам нужно передать строку. то есть.

t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')

Ответ 4

Заметка для будущих посетителей. Если вам нужно заставить его работать в отладчике pdb, а superMegaIntenseFunction не находится в глобальной области, вы можете заставить его работать, добавив в globals:

globals()['superMegaIntenseFunction'] = superMegaIntenseFunction
timeit.timeit(lambda: superMegaIntenseFunction(x))

Обратите внимание, что временные накладные расходы немного больше в этом случае из-за дополнительных вызовов функций. [источник]

Ответ 5

Один из способов сделать это - использовать частичный, чтобы функция "superMegaIntenseFunction" использовалась как вызываемая (т.е. Без()) в таймере или непосредственно внутри timeit.timeit. Использование partial передаст аргумент функции, когда он будет вызываться таймером.

from functools import partial
from timeit import timeit

print(timeit(partial(superMegaIntenseFunction, 10), number=1))