[Python-ideas] Timing hefty or long-running blocks of code

Masklinn masklinn at masklinn.net
Sat Jun 1 12:50:14 CEST 2013


On 2013-06-01, at 11:24 , Steven D'Aprano wrote:

> The timeit module is great for timing small code snippets, but it is rather inconvenient for timing larger blocks of code. It's also over-kill: under normal circumstances, there is little need for the heroic measures timeit goes through to accurately time long-running code.

Does timeit really go through much heroics when using it in code? The
CLI version does a bunch of testing and adaptation to try to get
accurate measures but as far as I know the Python API has no such
facilities, it runs what you gave it the number of time you tell it.

The only "heroics" it goes through is using timeit.default_timer(),
which is supposed to provide the most accurate clock available.

> When people want to time something that doesn't require timeit, they have to write their own timer boilerplate:
> 
> from time import time
> t = time()
> do_this()
> do_that()
> print(time() - t)
> 
> 
> Although only a few lines of boilerplate, this has a few problems, the biggest two being:
> 
> * the user has to decide which of the many clocks provided by Python
>  is suitable (hint: time.time is not necessarily the best);

But that's what timeit.default_timer() is for right? This seems to be a
problem of awareness more than availability.

> * this is inconvenient at the interactive interpreter, since the timer
>  is started before the code being typed has been entered.
> 
> I propose a context manager in the timeit module:
> 
> with Stopwatch():
>    do_this()
>    do_that()
> 
> => results are automatically printed, or available for programmatic access
> 
> I have had a recipe for this on ActiveState for about 18 months, where it is relatively popular:
> 
> http://code.activestate.com/recipes/577896-benchmark-code-with-the-with-statement
> 
> and I have extensively used it interactively, in Python 2.6 through 3.3 inclusive. The latest version can be found here:
> 
> https://code.google.com/p/my-startup-file/source/browse/timer.py
> 
> This solves the two problems listed above:
> 
> * the Stopwatch can use the most appropriate timer by default, and
>  allow the user to override it if they so choose;
> 
> * the Stopwatch will not start until the with-block is actually
>  entered.
> 
> 
> Is there interest in seeing this in the standard library?

A more general version can be achieved through timeit.Timer, though it's
got more boilerplate and as far as I know there's no example of it in
the documentation:

@timeit.Timer
def foo():
    do_this()
    do_that()
print foo.timeit(1)

On the other hand it allows repeated benching to try and refine the
iterations count.

Maybe context-management could simply be added to timeit.Timer,
rather than be a separate object?


More information about the Python-ideas mailing list