summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libtimeit.tex25
-rw-r--r--Lib/timeit.py64
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
4 files changed, 83 insertions, 11 deletions
diff --git a/Doc/lib/libtimeit.tex b/Doc/lib/libtimeit.tex
index 1c4e05b..f4f3cc7 100644
--- a/Doc/lib/libtimeit.tex
+++ b/Doc/lib/libtimeit.tex
@@ -31,6 +31,13 @@ To measure the execution time of the first statement, use the
\method{timeit()} method. The \method{repeat()} method is a
convenience to call \method{timeit()} multiple times and return a list
of results.
+
+\versionchanged[The \var{stmt} and \var{setup} parameters can now also
+ take objects that are callable without arguments. This
+ will embed calls to them in a timer function that will
+ then be executed by \method{timeit()}. Note that the timing
+ overhead is a little larger in this case because of the
+ extra function calls]{2.6}
\end{classdesc}
\begin{methoddesc}{print_exc}{\optional{file=\constant{None}}}
@@ -97,6 +104,24 @@ measured. If so, GC can be re-enabled as the first statement in the
\end{methoddesc}
+Starting with version 2.6, the module also defines two convenience functions:
+
+\begin{funcdesc}{repeat}{stmt\optional{, setup\optional{, timer\optional{,
+ repeat\code{=3} \optional{, number\code{=1000000}}}}}}
+Create a \class{Timer} instance with the given statement, setup code and timer
+function and run its \method{repeat} method with the given repeat count and
+\var{number} executions.
+\versionadded{2.6}
+\end{funcdesc}
+
+\begin{funcdesc}{timeit}{stmt\optional{, setup\optional{, timer\optional{,
+ number\code{=1000000}}}}}
+Create a \class{Timer} instance with the given statement, setup code and timer
+function and run its \method{timeit} method with \var{number} executions.
+\versionadded{2.6}
+\end{funcdesc}
+
+
\subsection{Command Line Interface}
When called as a program from the command line, the following form is used:
diff --git a/Lib/timeit.py b/Lib/timeit.py
index 8c0f7a5..09942f3 100644
--- a/Lib/timeit.py
+++ b/Lib/timeit.py
@@ -90,6 +90,17 @@ def reindent(src, indent):
"""Helper to reindent a multi-line statement."""
return src.replace("\n", "\n" + " "*indent)
+def _template_func(setup, func):
+ """Create a timer function. Used if the "statement" is a callable."""
+ def inner(_it, _timer):
+ setup()
+ _t0 = _timer()
+ for _i in _it:
+ func()
+ _t1 = _timer()
+ return _t1 - _t0
+ return inner
+
class Timer:
"""Class for timing execution speed of small code snippets.
@@ -109,14 +120,32 @@ class Timer:
def __init__(self, stmt="pass", setup="pass", timer=default_timer):
"""Constructor. See class doc string."""
self.timer = timer
- stmt = reindent(stmt, 8)
- setup = reindent(setup, 4)
- src = template % {'stmt': stmt, 'setup': setup}
- self.src = src # Save for traceback display
- code = compile(src, dummy_src_name, "exec")
ns = {}
- exec code in globals(), ns
- self.inner = ns["inner"]
+ if isinstance(stmt, basestring):
+ stmt = reindent(stmt, 8)
+ if isinstance(setup, basestring):
+ setup = reindent(setup, 4)
+ src = template % {'stmt': stmt, 'setup': setup}
+ elif callable(setup):
+ src = template % {'stmt': stmt, 'setup': '_setup()'}
+ ns['_setup'] = setup
+ else:
+ raise ValueError("setup is neither a string nor callable")
+ self.src = src # Save for traceback display
+ code = compile(src, dummy_src_name, "exec")
+ exec code in globals(), ns
+ self.inner = ns["inner"]
+ elif callable(stmt):
+ self.src = None
+ if isinstance(setup, basestring):
+ _setup = setup
+ def setup():
+ exec _setup in globals(), ns
+ elif not callable(setup):
+ raise ValueError("setup is neither a string nor callable")
+ self.inner = _template_func(setup, stmt)
+ else:
+ raise ValueError("stmt is neither a string nor callable")
def print_exc(self, file=None):
"""Helper to print a traceback from the timed code.
@@ -136,10 +165,13 @@ class Timer:
sent; it defaults to sys.stderr.
"""
import linecache, traceback
- linecache.cache[dummy_src_name] = (len(self.src),
- None,
- self.src.split("\n"),
- dummy_src_name)
+ if self.src is not None:
+ linecache.cache[dummy_src_name] = (len(self.src),
+ None,
+ self.src.split("\n"),
+ dummy_src_name)
+ # else the source is already stored somewhere else
+
traceback.print_exc(file=file)
def timeit(self, number=default_number):
@@ -189,6 +221,16 @@ class Timer:
r.append(t)
return r
+def timeit(stmt="pass", setup="pass", timer=default_timer,
+ number=default_number):
+ """Convenience function to create Timer object and call timeit method."""
+ return Timer(stmt, setup, timer).timeit(number)
+
+def repeat(stmt="pass", setup="pass", timer=default_timer,
+ repeat=default_repeat, number=default_number):
+ """Convenience function to create Timer object and call repeat method."""
+ return Timer(stmt, setup, timer).repeat(repeat, number)
+
def main(args=None):
"""Main program, used when run as a script.
diff --git a/Misc/ACKS b/Misc/ACKS
index 898af48..7b6002c 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -156,6 +156,7 @@ Ben Darnell
Jonathan Dasteel
John DeGood
Vincent Delft
+Erik Demaine
Roger Dev
Toby Dickenson
Yves Dionne
diff --git a/Misc/NEWS b/Misc/NEWS
index d03c4b5..ee4b538 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -168,6 +168,10 @@ Core and builtins
Library
-------
+- Patch #1533909: the timeit module now accepts callables in addition to
+ strings for the code to time and the setup code. Also added two
+ convenience functions for instantiating a Timer and calling its methods.
+
- Patch #1537850: tempfile.NamedTemporaryFile now has a "delete" parameter
which can be set to False to prevent the default delete-on-close
behavior.