Page 1 of 1

timeit module

#1 Nallo   User is offline

  • D.I.C Regular
  • member icon

Reputation: 165
  • View blog
  • Posts: 258
  • Joined: 19-July 09

Posted 06 August 2012 - 06:56 AM

This is a sequel to atraub's Calculating the runtime of a function tutorial.

Instead of writing your own timing code, I will show how to use the module timeit that is included in Python.
But first a question:
Why is there a time it module and why would you want to use it? After all the simple timing function from atraubs tutorial looks so simple:
import time

def simple_timer(func, *args):
	start = time.time()
	return time.time() - start

There are a few little problems:
You didn't turn the garbage collector of. If it works while you are timing you get unpredictable results.
You used time.time(). Fine on Linux, but don't forget to change that to time.clock() on a Windows machine. time.time on a Windows machine only measures in steps of 1/60 seconds.
By the time you thought about all those little details you probably have recreated the timeit module ;-)

Now lets start with a silly example:
>>> import timeit
>>> timer = timeit.Timer(stmt='print "I will be timed"',
			 setup='print "I am the setup code"')
>>> total_time = timer.timeit(number=3)
I am the setup code
I will be timed
I will be timed
I will be timed
>>> print total_time
>>> times = timer.repeat(repeat = 2, number = 1)
I am the setup code
I will be timed
I am the setup code
I will be timed
>>> print times
[0.0035791397094726562, 0.0040519237518310547]

What did we do? Obviously first we imported the timeit module. Then we set up the timing environment, by passing python code as two strings to timeit.Timer.
Timer takes two arguments: setup and stmt. setup will be executed, before we actually measure the execution time and stmt is the code we actually want to measure.
They default to 'pass', so when you don't need any setup code you can omit setup.

The Timer class has two methods, timeit and repeat. When we use timeit, we pass it an argument number. It runs the setup code once
and then executes statement number times. It returns the total time it took for that (excluding the setup of course). The default value for number is 1000000 in case you don't pass it the argument.

repeat takes two arguments, repeat and number. I guess you already figured out: In our example it does the same as if we were running timer.timeit(number=1) two times and put the results in a list.

That is all fine, but we usually want to time a function we already have written. We don't want to put that whole code in triple quotes, we want to pass it directly to timeit.Timer. How do we do that? You might think of the following:
>>> import timeit
>>> def silly(x):
	return x

>>> timer = timeit.Timer(stmt='f(3)')
>>> print timer.timeit(10)
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    print timer.timeit(10)
  File "/usr/lib/python2.6/", line 193, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
NameError: global name 'f' is not defined

Oops, what happened? timeit sets up it's own namespace for running the test code. An isolated namespace might be a good idea, but f isn't defined there. We need to import f into that namespace first:
import timeit

def silly(x):
    return x

timer = timeit.Timer(stmt='silly(3)', setup='from __main__ import silly')
print timer.timeit(number=10)

That is the main recipe for using timeit. Obviously, if silly was in a different module we would replace __main__ with silly's module name.

There are two convenience functions in the timeit module, timeit and repeat. They are just little wrappers that spare us some typing. We can call them like:
timeit.timeit(stmt=..., setup=..., number=...)

instead of:
timer = timeit.Timer(stmt, setup)

A few more notes:
timeit.Timer takes a third optional argument, timer. But usually you are fine with the defaults (time.time on Linux, time.clock on Windows)

timeit can also be used from the command line. Just type in
python -m timeit -h

to see how to use it. Is is rather self explaining.

Also timeit is meant to measure execution time for 'small' bits of code, like isolated functions. The problem is not that is easily chokes on larger programs. But for that purpose there are better tools.
You might want to see which function called which function how many times and how long that took respectively. cProfile come to mind for that purpose.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1