| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :mod:`timeit` --- Measure execution time of small code snippets
 | 
					
						
							|  |  |  | ===============================================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. module:: timeit
 | 
					
						
							|  |  |  |    :synopsis: Measure the execution time of small code snippets.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. index::
 | 
					
						
							|  |  |  |    single: Benchmarking
 | 
					
						
							|  |  |  |    single: Performance
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This module provides a simple way to time small bits of Python code. It has both
 | 
					
						
							|  |  |  | command line as well as callable interfaces.  It avoids a number of common traps
 | 
					
						
							|  |  |  | for measuring execution times.  See also Tim Peters' introduction to the
 | 
					
						
							|  |  |  | "Algorithms" chapter in the Python Cookbook, published by O'Reilly.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The module defines the following public class:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. class:: Timer([stmt='pass' [, setup='pass' [, timer=<timer function>]]])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Class for timing execution speed of small code snippets.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The constructor takes a statement to be timed, an additional statement used for
 | 
					
						
							|  |  |  |    setup, and a timer function.  Both statements default to ``'pass'``; the timer
 | 
					
						
							|  |  |  |    function is platform-dependent (see the module doc string).  The statements may
 | 
					
						
							|  |  |  |    contain newlines, as long as they don't contain multi-line string literals.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    To measure the execution time of the first statement, use the :meth:`timeit`
 | 
					
						
							|  |  |  |    method.  The :meth:`repeat` method is a convenience to call :meth:`timeit`
 | 
					
						
							|  |  |  |    multiple times and return a list of results.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-01 13:51:09 +00:00
										 |  |  |    The *stmt* and *setup* parameters can also take objects that are callable
 | 
					
						
							|  |  |  |    without arguments. This will embed calls to them in a timer function that
 | 
					
						
							|  |  |  |    will then be executed by :meth:`timeit`.  Note that the timing overhead is a
 | 
					
						
							|  |  |  |    little larger in this case because of the extra function calls.
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: Timer.print_exc([file=None])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Helper to print a traceback from the timed code.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Typical use::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       t = Timer(...)       # outside the try/except
 | 
					
						
							|  |  |  |       try:
 | 
					
						
							|  |  |  |           t.timeit(...)    # or t.repeat(...)
 | 
					
						
							|  |  |  |       except:
 | 
					
						
							|  |  |  |           t.print_exc()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The advantage over the standard traceback is that source lines in the compiled
 | 
					
						
							|  |  |  |    template will be displayed. The optional *file* argument directs where the
 | 
					
						
							|  |  |  |    traceback is sent; it defaults to ``sys.stderr``.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: Timer.repeat([repeat=3 [, number=1000000]])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Call :meth:`timeit` a few times.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This is a convenience function that calls the :meth:`timeit` repeatedly,
 | 
					
						
							|  |  |  |    returning a list of results.  The first argument specifies how many times to
 | 
					
						
							|  |  |  |    call :meth:`timeit`.  The second argument specifies the *number* argument for
 | 
					
						
							|  |  |  |    :func:`timeit`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. note::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       It's tempting to calculate mean and standard deviation from the result vector
 | 
					
						
							|  |  |  |       and report these.  However, this is not very useful.  In a typical case, the
 | 
					
						
							|  |  |  |       lowest value gives a lower bound for how fast your machine can run the given
 | 
					
						
							|  |  |  |       code snippet; higher values in the result vector are typically not caused by
 | 
					
						
							|  |  |  |       variability in Python's speed, but by other processes interfering with your
 | 
					
						
							|  |  |  |       timing accuracy.  So the :func:`min` of the result is probably the only number
 | 
					
						
							|  |  |  |       you should be interested in.  After that, you should look at the entire vector
 | 
					
						
							|  |  |  |       and apply common sense rather than statistics.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. method:: Timer.timeit([number=1000000])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Time *number* executions of the main statement. This executes the setup
 | 
					
						
							|  |  |  |    statement once, and then returns the time it takes to execute the main statement
 | 
					
						
							|  |  |  |    a number of times, measured in seconds as a float.  The argument is the number
 | 
					
						
							|  |  |  |    of times through the loop, defaulting to one million.  The main statement, the
 | 
					
						
							|  |  |  |    setup statement and the timer function to be used are passed to the constructor.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    .. note::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												Merged revisions 59259-59274 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
  r59260 | lars.gustaebel | 2007-12-01 22:02:12 +0100 (Sat, 01 Dec 2007) | 5 lines
  Issue #1531: Read fileobj from the current offset, do not seek to
  the start.
  (will backport to 2.5)
........
  r59262 | georg.brandl | 2007-12-01 23:24:47 +0100 (Sat, 01 Dec 2007) | 4 lines
  Document PyEval_* functions from ceval.c.
  Credits to Michael Sloan from GHOP.
........
  r59263 | georg.brandl | 2007-12-01 23:27:56 +0100 (Sat, 01 Dec 2007) | 2 lines
  Add a few refcount data entries.
........
  r59264 | georg.brandl | 2007-12-01 23:38:48 +0100 (Sat, 01 Dec 2007) | 4 lines
  Add test suite for cmd module.
  Written by Michael Schneider for GHOP.
........
  r59265 | georg.brandl | 2007-12-01 23:42:46 +0100 (Sat, 01 Dec 2007) | 3 lines
  Add examples to the ElementTree documentation.
  Written by h4wk.cz for GHOP.
........
  r59266 | georg.brandl | 2007-12-02 00:12:45 +0100 (Sun, 02 Dec 2007) | 3 lines
  Add "Using Python on Windows" document, by Robert Lehmann.
  Written for GHOP.
........
  r59271 | georg.brandl | 2007-12-02 15:34:34 +0100 (Sun, 02 Dec 2007) | 3 lines
  Add example to mmap docs.
  Written for GHOP by Rafal Rawicki.
........
  r59272 | georg.brandl | 2007-12-02 15:37:29 +0100 (Sun, 02 Dec 2007) | 2 lines
  Convert bdb.rst line endings to Unix style.
........
  r59274 | georg.brandl | 2007-12-02 15:58:50 +0100 (Sun, 02 Dec 2007) | 4 lines
  Add more entries to the glossary.
  Written by Jeff Wheeler for GHOP.
........
											
										 
											2007-12-02 15:22:16 +00:00
										 |  |  |       By default, :meth:`timeit` temporarily turns off :term:`garbage collection`
 | 
					
						
							|  |  |  |       during the timing.  The advantage of this approach is that it makes
 | 
					
						
							|  |  |  |       independent timings more comparable.  This disadvantage is that GC may be
 | 
					
						
							|  |  |  |       an important component of the performance of the function being measured.
 | 
					
						
							|  |  |  |       If so, GC can be re-enabled as the first statement in the *setup* string.
 | 
					
						
							|  |  |  |       For example::
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |          timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-12 18:05:20 +00:00
										 |  |  | The module also defines two convenience functions:
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | .. function:: repeat(stmt[, setup[, timer[, repeat=3 [, number=1000000]]]])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Create a :class:`Timer` instance with the given statement, setup code and timer
 | 
					
						
							|  |  |  |    function and run its :meth:`repeat` method with the given repeat count and
 | 
					
						
							|  |  |  |    *number* executions.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. function:: timeit(stmt[, setup[, timer[, number=1000000]]])
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Create a :class:`Timer` instance with the given statement, setup code and timer
 | 
					
						
							|  |  |  |    function and run its :meth:`timeit` method with *number* executions.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Command Line Interface
 | 
					
						
							|  |  |  | ----------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When called as a program from the command line, the following form is used::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...]
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | where the following options are understood:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -n N/:option:`--number=N`
 | 
					
						
							|  |  |  |    how many times to execute 'statement'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -r N/:option:`--repeat=N`
 | 
					
						
							|  |  |  |    how many times to repeat the timer (default 3)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -s S/:option:`--setup=S`
 | 
					
						
							|  |  |  |    statement to be executed once initially (default ``'pass'``)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -t/:option:`--time`
 | 
					
						
							|  |  |  |    use :func:`time.time` (default on all platforms but Windows)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -c/:option:`--clock`
 | 
					
						
							|  |  |  |    use :func:`time.clock` (default on Windows)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -v/:option:`--verbose`
 | 
					
						
							|  |  |  |    print raw timing results; repeat for more digits precision
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -h/:option:`--help`
 | 
					
						
							|  |  |  |    print a short usage message and exit
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A multi-line statement may be given by specifying each line as a separate
 | 
					
						
							|  |  |  | statement argument; indented lines are possible by enclosing an argument in
 | 
					
						
							|  |  |  | quotes and using leading spaces.  Multiple :option:`-s` options are treated
 | 
					
						
							|  |  |  | similarly.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If :option:`-n` is not given, a suitable number of loops is calculated by trying
 | 
					
						
							|  |  |  | successive powers of 10 until the total time is at least 0.2 seconds.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The default timer function is platform dependent.  On Windows,
 | 
					
						
							|  |  |  | :func:`time.clock` has microsecond granularity but :func:`time.time`'s
 | 
					
						
							|  |  |  | granularity is 1/60th of a second; on Unix, :func:`time.clock` has 1/100th of a
 | 
					
						
							|  |  |  | second granularity and :func:`time.time` is much more precise.  On either
 | 
					
						
							|  |  |  | platform, the default timer functions measure wall clock time, not the CPU time.
 | 
					
						
							|  |  |  | This means that other processes running on the same computer may interfere with
 | 
					
						
							|  |  |  | the timing.  The best thing to do when accurate timing is necessary is to repeat
 | 
					
						
							|  |  |  | the timing a few times and use the best time.  The :option:`-r` option is good
 | 
					
						
							|  |  |  | for this; the default of 3 repetitions is probably enough in most cases.  On
 | 
					
						
							|  |  |  | Unix, you can use :func:`time.clock` to measure CPU time.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. note::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    There is a certain baseline overhead associated with executing a pass statement.
 | 
					
						
							|  |  |  |    The code here doesn't try to hide it, but you should be aware of it.  The
 | 
					
						
							|  |  |  |    baseline overhead can be measured by invoking the program without arguments.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The baseline overhead differs between Python versions!  Also, to fairly compare
 | 
					
						
							|  |  |  | older Python versions to Python 2.3, you may want to use Python's :option:`-O`
 | 
					
						
							|  |  |  | option for the older versions to avoid timing ``SET_LINENO`` instructions.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Examples
 | 
					
						
							|  |  |  | --------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here are two example sessions (one using the command line, one using the module
 | 
					
						
							|  |  |  | interface) that compare the cost of using :func:`hasattr` vs.
 | 
					
						
							|  |  |  | :keyword:`try`/:keyword:`except` to test for missing and present object
 | 
					
						
							|  |  |  | attributes. ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % timeit.py 'try:' '  str.__bool__' 'except AttributeError:' '  pass'
 | 
					
						
							|  |  |  |    100000 loops, best of 3: 15.7 usec per loop
 | 
					
						
							|  |  |  |    % timeit.py 'if hasattr(str, "__bool__"): pass'
 | 
					
						
							|  |  |  |    100000 loops, best of 3: 4.26 usec per loop
 | 
					
						
							|  |  |  |    % timeit.py 'try:' '  int.__bool__' 'except AttributeError:' '  pass'
 | 
					
						
							|  |  |  |    1000000 loops, best of 3: 1.43 usec per loop
 | 
					
						
							|  |  |  |    % timeit.py 'if hasattr(int, "__bool__"): pass'
 | 
					
						
							|  |  |  |    100000 loops, best of 3: 2.23 usec per loop
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    >>> import timeit
 | 
					
						
							|  |  |  |    >>> s = """\
 | 
					
						
							|  |  |  |    ... try:
 | 
					
						
							|  |  |  |    ...     str.__bool__
 | 
					
						
							|  |  |  |    ... except AttributeError:
 | 
					
						
							|  |  |  |    ...     pass
 | 
					
						
							|  |  |  |    ... """
 | 
					
						
							|  |  |  |    >>> t = timeit.Timer(stmt=s)
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |    >>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  |    17.09 usec/pass
 | 
					
						
							|  |  |  |    >>> s = """\
 | 
					
						
							|  |  |  |    ... if hasattr(str, '__bool__'): pass
 | 
					
						
							|  |  |  |    ... """
 | 
					
						
							|  |  |  |    >>> t = timeit.Timer(stmt=s)
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |    >>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  |    4.85 usec/pass
 | 
					
						
							|  |  |  |    >>> s = """\
 | 
					
						
							|  |  |  |    ... try:
 | 
					
						
							|  |  |  |    ...     int.__bool__
 | 
					
						
							|  |  |  |    ... except AttributeError:
 | 
					
						
							|  |  |  |    ...     pass
 | 
					
						
							|  |  |  |    ... """
 | 
					
						
							|  |  |  |    >>> t = timeit.Timer(stmt=s)
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |    >>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  |    1.97 usec/pass
 | 
					
						
							|  |  |  |    >>> s = """\
 | 
					
						
							|  |  |  |    ... if hasattr(int, '__bool__'): pass
 | 
					
						
							|  |  |  |    ... """
 | 
					
						
							|  |  |  |    >>> t = timeit.Timer(stmt=s)
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |    >>> print("%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000))
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  |    3.15 usec/pass
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To give the :mod:`timeit` module access to functions you define, you can pass a
 | 
					
						
							|  |  |  | ``setup`` parameter which contains an import statement::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    def test():
 | 
					
						
							|  |  |  |        "Stupid test function"
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |        L = [i for i in range(100)]
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    if __name__=='__main__':
 | 
					
						
							|  |  |  |        from timeit import Timer
 | 
					
						
							|  |  |  |        t = Timer("test()", "from __main__ import test")
 | 
					
						
							| 
									
										
										
										
											2007-09-01 23:34:30 +00:00
										 |  |  |        print(t.timeit())
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 |