Inspired by this post I wrote this context manager to benchmark code blocks or function calls.
Usage is incredibly simple:
with Timer(): ... # code to benchmark goes here
The time taken (in seconds) will be printed when the code block completes. To capture the time taken programmatically is almost as easy:
t = Timer() with t: ... # code to benchmark goes here time_taken = t.interval
Due to the difficulties of timing small snippets of code accurately, you should only use this for timing code blocks or function calls which take a significant amount of time to process. For micro-benchmarks, you should use the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
import gc import timeit import time class Timer: def __init__(self, timer=None, disable_gc=False, verbose=True): if timer is None: timer = timeit.default_timer self.timer = timer self.disable_gc = disable_gc self.verbose = verbose self.start = self.end = self.interval = None def __enter__(self): if self.disable_gc: self.gc_state = gc.isenabled() gc.disable() self.start = self.timer() return self def __exit__(self, *args): self.end = self.timer() if self.disable_gc and self.gc_state: gc.enable() self.interval = self.end - self.start if self.verbose: print('time taken: %f seconds' % self.interval)
The hard part of timing code snippets accurately is that the operating system and other running processes get in the way. This makes micro-benchmarks hard to perform accurately, and the
timeit module is designed for this purpose. But for more heavyweight code, the noise introduced by the OS is usually unimportant (although if your anti-virus scanner decides to schedule a full disk scan just as your test starts, your results may be affected...), and using timeit doesn't gain you very much and this is much more convenient.
This should work in any version of Python from 2.5 onwards. In 2.5, you will need to enable the with statement first:
from __future__ import with_statement
Timer object takes three optional arguments: a timer function, a flag telling it whether or not to disable Python's garbage collector, and a verbose flag.
The usual choices for the timer function are
time.clock (usually best for Windows) or
time.time (usually best for other platforms). By default, it will use the platform-specific default timer from the
If the second argument is true, the garbage collector will be disabled just before running the code block, and then reverted to its previous state afterwards. By default the garbage collector is left alone.
If the third argument is true, the benchmark is printed just after finishing. Note that if an exception takes place inside the block, the benchmark will still be printed just before the traceback.