Pages

June 17, 2012

Python Timer Class - Context Manager for Timing Code Blocks

Here is a handy Python Timer class. It creates a context manager object, used for timing a block of code.

from timeit import default_timer


class Timer(object):
    def __init__(self, verbose=False):
        self.verbose = verbose
        self.timer = default_timer
        
    def __enter__(self):
        self.start = self.timer()
        return self
        
    def __exit__(self, *args):
        end = self.timer()
        self.elapsed_secs = end - self.start
        self.elapsed = self.elapsed_secs * 1000  # millisecs
        if self.verbose:
            print 'elapsed time: %f ms' % self.elapsed

To use the Timer (context manager object), invoke it using Python's `with` statement. The duration of the context (code inside your `with` block) will be timed. It uses the appropriate timer for your platform, via the `timeit` module.

Timer is used like this:

with Timer() as target:
    # block of code goes here.
    # result (elapsed time) is stored in `target` properties.

Example script:
timing a web request (HTTP GET), using the `requests` module.

#!/usr/bin/env python

import requests
from timer import Timer

url = 'https://github.com/timeline.json'

with Timer() as t:
    r = requests.get(url)
    
print 'fetched %r in %.2f millisecs' % (url, t.elapsed)

Output:

fetched 'https://github.com/timeline.json' in 458.76 millisecs

`timer.py` in GitHub Gist form, with more examples:

8 comments:

  1. I have something very similar in my utils, but you can also give it a name: https://gist.github.com/2944722

    ReplyDelete
  2. AnonymousJune 18, 2012

    I've been using decorators for this. I'll have to see how hard it would be to add context manager syntax support in profilehooks.

    ReplyDelete
  3. Very cool tool! timeit can be a pain to use, because of it string statement argument.

    This seems much more natural to use. Kudos!

    ReplyDelete
  4. I did something similar. I also added an option to append the timings to a CSV, since I was trying to optimize a time sensitive piece of code.

    I wasn't aware of default_timer. TIL. :-)

    https://gist.github.com/2948552

    ReplyDelete
  5. Thanks!

    Very useful timer class, a good use of context manager

    ReplyDelete
  6. AnonymousJune 20, 2012

    https://github.com/jsocol/pystatsd/blob/master/statsd/client.py - similar idea also usable as a decorator.

    ReplyDelete
  7. I am receiving an error in attempting to import the requests module. Is this pseudo-code? From where are your importing this?

    ReplyDelete
  8. @chrisk

    you need to install `requests` (a *great* module).

    see: http://docs.python-requests.org/

    or `pip install requests`

    -Corey

    ReplyDelete