Suppose I have some function that takes an array and changes every element to be 0.
def function(array):
for i in range(0,len(array)):
array[i] = 0
return array
I want to test how long this function takes to run on a random array, which I wish to generate OUTSIDE of the timeit test. In other words, I don't want to include the time it takes to generate the array into the time.
I first store a random array in a variable x and do:
timeit.timeit("function(x)",setup="from __main__ import function")
But this gives me an error: NameError: global name 'x' is not defined
How can I do this?
Import
x
from__main__
as well:Just like
function
,x
is a name in the__main__
module, and can be imported into thetimeit
setup.Alternatively, you can add
x
toglobals
. The good thing about it is that it works in apdb
debugging session:You can avoid this problem entirely if you pass
timeit
a function instead of a string. In that case, the function executes in its normal globals and closure environment. So:Or, if you prefer:
(See here for details. Note that it requires Python 2.6+, so if you need 2.3-2.5, you can't use this trick.)
As the documentation says, "Note that the timing overhead is a little larger in this case because of the extra function calls."
This means that it makes
timeit
itself run slower. For example:However, it doesn't affect the actual results:
(In the rare cases where it does, that typically means one version or the other wasn't testing the function the way it will be called in your real code, or was testing the wrong closure or similar.)
Note that the actual time taken inside the function here is about 88 seconds, so we've nearly doubled the overhead of timing code… but it's still only added 3% to the total testing time. And the less trivial
f
is, the smaller this difference will be.With Python 3.5, the optional argument
globals
has been introduced. It makes it possible to specify the namespace in which the timeit statement shall be executed.So instead of writing:
timeit.timeit("function(x), setup="from __main__ import function, x")
...you can now write:
timeit.timeit("function(x)", globals=globals())
Import
x
from__main__
: