Как использовать 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

Если я запускаю функцию, он отлично работает. Его, когда я обертываю его в модуле time it, Я получаю ошибки(я пробовал использовать двойные кавычки и без..sameoutput).

любые предложения было бы здорово!

спасибо!

4 66

4 ответа:

сделать его вызываемым:

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))

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