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.
This commit is contained in:
parent
4168c0466f
commit
d9bef35e3c
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ Ben Darnell
|
|||
Jonathan Dasteel
|
||||
John DeGood
|
||||
Vincent Delft
|
||||
Erik Demaine
|
||||
Roger Dev
|
||||
Toby Dickenson
|
||||
Yves Dionne
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue