how to pass parameters of a function when using timeit.Timer()
This is the outline of a simple program
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
import timeit
t = timeit.Timer(stmt="foo(num1,num2)")
print t.timeit(5)
I just keep getting "global name foo is not defined"..... Can anyone help me on this? Thanks!
Solution 1:
The functions can use arguments in timeit
if these are created using closures, we can add this behaviours by wrapping them in another function.
def foo(num1, num2):
def _foo():
# do something to num1 and num2
pass
return _foo
A = 1
B = 2
import timeit
t = timeit.Timer(foo(A,B))
print(t.timeit(5))
or shorter, we can use functools.partial instead of explicit closures declaration
def foo(num1, num2):
# do something to num1 and num2
pass
A = 1
B = 2
import timeit, functools
t = timeit.Timer(functools.partial(foo, A, B))
print(t.timeit(5))
EDIT using lambda, thanks @jupiterbjy
we can use lambda function without parameters instead of functools library
def foo(num1, num2):
# do something to num1 and num2
pass
A = 1
B = 2
import timeit
t = timeit.Timer(lambda: foo(A, B))
print (t.timeit(5))
Solution 2:
The code snippets must be self-contained - they cannot make external references. You must define your values in the statement-string or setup-string:
import timeit
setup = """
A = 1
B = 2
def foo(num1, num2):
pass
def mainprog():
global A,B
for i in range(20):
# do something to A and B
foo(A, B)
"""
t = timeit.Timer(stmt="mainprog()" setup=setup)
print(t.timeit(5))
Better yet, rewrite your code to not use global values.
Solution 3:
Supposing that your module filename is test.py
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(n, m):
pass
# main program.... do something to A and B
for i in range(20):
pass
import timeit
t = timeit.Timer(stmt="test.foo(test.A, test.B)", setup="import test")
print t.timeit(5)
Solution 4:
I usually create an extra function:
def f(x,y):
return x*y
v1 = 10
v2 = 20
def f_test():
f(v1,v2)
print(timeit.timeit("f_test()", setup="from __main__ import f_test"))
Solution 5:
Your function needs to be define in the setup string. A good way to do this is by setting up your code in a module, so you simple have to do
t = timeit.Timer("foo(num1, num2)", "from myfile import foo")
t.timeit(5)
Otherwise, you'll have to define all of the setup as a string inside the setup statement.
setup = """
# some pre-defined constants
A = 1
B = 2
# function that does something critical
def foo(num1, num2):
# do something
# main program.... do something to A and B
for i in range(20):
# do something to A and B
# and update A and B during each iteration
"""
t = timeit.Timer("foo(num1, num2)", setup)
t.timeit(5)
Something awesome I just found out about is a shortcut for iPython that uses cProfile.
def foo(x, y):
print x*y
%prun foo("foo", 100)