Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "global name 'foo' is not defined" with Python's timeit

I'm trying to find out how much time it takes to execute a Python statement, so I looked online and found that the standard library provides a module called timeit that purports to do exactly that:

import timeit

def foo():
    # ... contains code I want to time ...

def dotime():
    t = timeit.Timer("foo()")
    time = t.timeit(1)
    print "took %fs\n" % (time,)

dotime()

However, this produces an error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in dotime
  File "/usr/local/lib/python2.6/timeit.py", line 193, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
NameError: global name 'foo' is not defined

I'm still new to Python and I don't fully understand all the scoping issues it has, but I don't know why this snippet doesn't work. Any thoughts?

like image 453
Kyle Cronin Avatar asked Feb 15 '09 23:02

Kyle Cronin


People also ask

What does %% Timeit do in Python?

%%timeit. You can use the magic command %%timeit to measure the execution time of the cell. As an example, try executing the same process using NumPy . As with %timeit , -n and -r are optional.

What is the difference between %Timeit and %% Timeit?

The “%timeit” is a line magic command in which the code consists of a single line or should be written in the same line for measuring the execution time. In the “%timeit” command, the particular code is specified after the “%timeit” is separated by a space.


3 Answers

Change this line:

t = timeit.Timer("foo()")

To this:

t = timeit.Timer("foo()", "from __main__ import foo")

Check out the link you provided at the very bottom.

To give the timeit module access to functions you define, you can pass a setup parameter which contains an import statement:

I just tested it on my machine and it worked with the changes.

like image 80
Paolo Bergantino Avatar answered Nov 07 '22 04:11

Paolo Bergantino


With Python 3, you can use globals=globals()

t = timeit.Timer("foo()", globals=globals())

From the documentation:

Another option is to pass globals() to the globals parameter, which will cause the code to be executed within your current global namespace. This can be more convenient than individually specifying imports

like image 37
user2314737 Avatar answered Nov 07 '22 03:11

user2314737


You can try this hack:

import timeit

def foo():
    print 'bar'

def dotime():
    t = timeit.Timer("foo()")
    time = t.timeit(1)
    print "took %fs\n" % (time,)

import __builtin__
__builtin__.__dict__.update(locals())

dotime()
like image 21
Luka Zakrajšek Avatar answered Nov 07 '22 04:11

Luka Zakrajšek