How to use python timeit when passing variables to functions?
I'm struggling with this using timeit and was wondering if anyone had any tips
Basically I have a function(that I pass a value to) that I want to test the speed of and created this:
if __name__=='__main__':
from timeit import Timer
t = Timer(superMegaIntenseFunction(10))
print t.timeit(number=1)
but when I run it, I get weird errors like coming from the timeit module.:
ValueError: stmt is neither a string nor callable
If I run the function on its own, it works fine. Its when I wrap it in the time it module, I get the errors(I have tried using double quotes and without..sameoutput).
any suggestions would be awesome!
Thanks!
Make it a callable:
if __name__=='__main__':
from timeit import Timer
t = Timer(lambda: superMegaIntenseFunction(10))
print(t.timeit(number=1))
Should work
Timer(superMegaIntenseFunction(10))
means "call superMegaIntenseFunction(10)
, then pass the result to Timer
". That's clearly not what you want. Timer
expects either a callable (just as it sounds: something that can be called, such as a function), or a string (so that it can interpret the contents of the string as Python code). Timer
works by calling the callable-thing repeatedly and seeing how much time is taken.
Timer(superMegaIntenseFunction)
would pass the type check, because superMegaIntenseFunction
is callable. However, Timer
wouldn't know what values to pass to superMegaIntenseFunction
.
The simple way around this, of course, is to use a string with the code. We need to pass a 'setup' argument to the code, because the string is "interpreted as code" in a fresh context - it doesn't have access to the same globals
, so you need to run another bit of code to make the definition available - see @oxtopus's answer.
With lambda
(as in @Pablo's answer), we can bind the parameter 10
to a call to superMegaIntenseFunction
. All that we're doing is creating another function, that takes no arguments, and calls superMegaIntenseFunction
with 10
. It's just as if you'd used def
to create another function like that, except that the new function doesn't get a name (because it doesn't need one).
You should be passing a string. i.e.
t = Timer('superMegaIntenseFunction(10)','from __main__ import superMegaIntenseFunction')