Passing function objects to timeit

Peter Otten __peter__ at web.de
Sun Mar 30 15:03:21 CEST 2008


Steven D'Aprano wrote:

> On Sun, 30 Mar 2008 01:27:18 -0300, Gabriel Genellina wrote:
> 
>> Second try:
> ...
>> Horrible, I know. Those wrapper1,wrapper2,wrapper3... keep growing with
>> each call. But it's the only way I could find, at least without changing
>> the code template used by timeit.
> 
> Eeek. Talk about namespace pollution.
> 
> Thanks for the effort, but if that's the only solution, I think the
> solution is worse than the problem!
> 
> Perhaps it's time for me to take a different approach. 
[snip]

Maybe the following enhancement of timeit would be worthwhile?

$ cat timeanyfunc.py

from mytimeit import Timer

def functionA():
    print "Function A"

def functionB():
    print "Function B"

T1 = Timer("f()", ns=dict(f=functionA))
T2 = Timer("f()", ns=dict(f=functionB))

T1.repeat(3, 1)
T2.repeat(3, 1)

$ python timeanyfunc.py
Function A
Function A
Function A
Function B
Function B
Function B

$ diff -u /usr/lib/python2.5/timeit.py mytimeit.py
--- /usr/lib/python2.5/timeit.py        2008-03-07 05:35:55.000000000 +0100
+++ mytimeit.py 2008-03-30 14:40:58.000000000 +0200
@@ -77,7 +77,7 @@
 # in Timer.__init__() depend on setup being indented 4 spaces and stmt
 # being indented 8 spaces.
 template = """
-def inner(_it, _timer):
+def inner(_it, _timer, %(inject)s):
     %(setup)s
     _t0 = _timer()
     for _i in _it:
@@ -106,15 +106,16 @@
     multi-line string literals.
     """

-    def __init__(self, stmt="pass", setup="pass", timer=default_timer):
+    def __init__(self, stmt="pass", setup="pass", timer=default_timer, ns=None):
         """Constructor.  See class doc string."""
+        if ns is None:
+            ns = {}
         self.timer = timer
         stmt = reindent(stmt, 8)
         setup = reindent(setup, 4)
-        src = template % {'stmt': stmt, 'setup': setup}
+        src = template % {'stmt': stmt, 'setup': setup, 'inject': ','.join("%s=%s" % (s, s) for s in ns)}
         self.src = src # Save for traceback display
         code = compile(src, dummy_src_name, "exec")
-        ns = {}
         exec code in globals(), ns
         self.inner = ns["inner"]

By the way, haven't we been there before, two years ago?

http://mail.python.org/pipermail/python-list/2006-February/368341.html

Peter



More information about the Python-list mailing list