Simple Timer using Python’s With Statement

Python’s with statement, available since Python 2.5, does not seem to be widely used despite being very useful.

Here we describe how to use the with statement to create a simple timer with the syntax:

>>> with TicToc():
...     some_slow_operations
...
Elapsed time is 2.000073 seconds.

Readers familiar with MATLAB will recognize the similarity to the familiar timing mechanism:

> tic ; some_slow_operations; toc
Elapsed time is 10.020349 seconds.

Before we describe the TicToc class, let’s review the with statement. The documentation for reading files suggests that it is a good way to ensure files are properly closed, even if the code reading them raises an exception.

>>> with open('/tmp/workfile', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

The with statement uses two methods, __enter__, which is run before the block executes, and __exit__, which is run after the block executes even if an exception is raised.  With this in mind, the previous code is mostly equivalent to:

>>> f = open('/tmp/workfile', 'r')
>>> f.__enter__()
<open file '/tmp/workfile', mode 'r' at 0x10041d810>
>>> read_data = f.read()
>>> f.__exit__(None, None, None)
>>> f.closed
True

Here the method file.__exit__ has automatically closed the file.

TicToc

The timer will be implemented as a class defining two methods:

  1. __enter__ which records the start time.
  2. __exit__ which prints the difference between the current time and the start time.
The actual code to simpletimer.py is quite short:
import time
class TicToc(object):
    """
    A simple code timer.

    Example
    -------
    >>> with TicToc():
    ...     time.sleep(2)
    Elapsed time is 2.000073 seconds.
    """
    def __init__(self, do_print = True):
        self.do_print = do_print
    def __enter__(self):
        self.start_time = time.time()
        return self
    def __exit__(self, type, value, traceback):
        self.elapsed = time.time() - self.start_time
        if self.do_print:
            print "Elapsed time is %f seconds." % self.elapsed
Usage is simple:
>>> from simpletimer import TicToc
>>> import time
>>> with TicToc():
...     time.sleep(2)
...
Elapsed time is 2.000115 seconds.
>>> with TicToc(False) as t:
...     time.sleep(1)
...
>>> t.elapsed
1.0001189708709717
About these ads

One thought on “Simple Timer using Python’s With Statement

  1. I think a better characterization of a with statement is as a try, finally block. So the open example is actually the same as (I hope WordPress doesn’t kill my indentation)

    try:
    f = open(‘/tmp/workfile’, ‘r’)
    read_data = f.read()
    finally:
    f.close()

    The important thing being that the f.close() is *always* run, even if some unexpected exception is raised. You can even call “return” and it will still be called. It’s the same with __exit__ in a context manager.

    And by the way, if you want to use the with statement in Python 2.5, you have to add “from __future__ import with_statement” to the top of the file (or type that out if you’re running interactively).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s