In all of the places I read about timeit I found only that I can use variables in this way:
s1 = 'abc'
s2 = 'abc'
timeit.timeit('s1==s2', 'from __main__ import s1, s2', number=10**4)
or
s1 = 'abc'
s2 = 'abc'
def func():
timeit.time('s1==s2', 'from __main__ import s1,s2', number=10**4)
which means that you can also use timeit.timeit in a function as long as the variables are in the main program. I would like to use timeit.timeit with variables that are within the scope it is in, for example:
def func():
s1 = 'abc'
s2 = 'abc'
timeit.timeit(...)
As you can see my question is:
How can I use timeit.timeit with the variables that are in the same scope, when they're both not in the main program?
Module Contents The timeit() method runs the setup statement one time, then executes the primary statement repeatedly and returns the amount of time that passes. The argument to timeit() controls how many times to run the statement; the default is 1,000,000.
Source code: Lib/timeit.py. This module provides a simple way to time small bits of Python code. It has both a Command-Line Interface as well as a callable one. It avoids a number of common traps for measuring execution times.
The Python timeit() method accepts the code as a string and returns the execution time in seconds. On the contrary, the default_timer() method returns the time of its execution. The repeat() method calls the timeit() method a number of specified times.
I would like to use timeit.timeit with variables that are within the scope it is in.
TLDR:
Use a lambda
closure (so called because it closes over the variables in the function):
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit(lambda: s1 == s2)
And I think that's just about what you're asking for.
>>> func()
0.12512516975402832
Explanation
So in the global scope, you want to use the globals, and local scope, locals? On the global scope, locals()
returns the same as globals()
, so it you ', '.join(locals())
and stick that on the end of 'from __main__ import '
, or globals()
as they're equivalent on the global scope:
>>> s1 = 'abc'
>>> s2 = 'abc'
>>> timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
0.14271061390928885
You could do this with a function and the globals()
too, but you can't use locals():
s1 = 'abc'
s2 = 'abc'
def func():
return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(globals()))
and
>>> func()
0.14236921612231157
but the below doesn't work, because you've got to have access to the variables hidden in the local scope of the function, from the import statement:
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit('s1==s2', 'from __main__ import ' + ', '.join(locals()))
But because you can simply pass the function to timeit, what you can do is this:
def func(s1='abc', s2='abc'):
s1 == s2
and
>>> timeit.timeit(func)
0.14399981498718262
So that also means, in your func, you can provide timeit a lambda closure:
def func():
s1 = 'abc'
s2 = 'abc'
return timeit.timeit(lambda: s1 == s2)
Or a full function def:
def func():
s1 = 'abc'
s2 = 'abc'
def closure():
return s1 == s2
return timeit.timeit(closure)
And I think that's just about what you're asking for.
>>> func()
0.12512516975402832
When they're both not in the main program
If you want to join the globals instead with a setup, from other modules than __main__
, use this:
'from ' + __name__ + ' import ' + ', '.join(globals())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With