msg64805 - (view) |
Author: Peter Otten (peter.otten) * |
Date: 2008-04-01 12:13 |
I'd like to suggest a different approach than the one taken in rev.
54348 to improve timeit's scripting interface: allow passing it a
namespace. Reasons:
- It has smaller overhead for functions that take an argument:
>>> def f(a): pass
...
# trunk
>>> min(ht.Timer(lambda f=f: f(42)).repeat())
0.54068493843078613
# my patch
>>> min(mt.Timer("f(42)", ns=dict(f=f)).repeat())
0.29009604454040527
- it is more flexible. Example:
# working code, requires matplotlib
from timeit import Timer
from time import sleep
def linear(i):
sleep(.05*i)
def quadratic(i):
sleep(.01*i**2)
x = range(10)
y = []
for a in x:
y.append([min(Timer("f(a)", ns=dict(f=f, a=a)).repeat(1, 1))
for f in linear, quadratic])
from pylab import plot, show
plot(x, y)
show()
The above code works unaltered inside a function, unlike the hacks
using "from __main__ import ...".
- the implementation is simpler and should be easy to maintain.
The provided patch is against 2.5.1. If it has a chance of being
accepted I'm willing to jump through the necessary hoops:
documentation, tests, etc.
|
msg64812 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2008-04-01 15:48 |
A more general approach would be to add both 'locals' and 'globals' to
be used by exec. At least, I would change 'ns' to 'locals'.
|
msg64814 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2008-04-01 15:53 |
On the second thought, I actually wanted Timer to mimic eval without
realizing that eval uses positional rather than keywords arguments.
'locals' is obviously a bad choice for the keyword parameter because it
masks locals() builtin. Maybe 'local_namespace'?
|
msg64816 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2008-04-01 18:50 |
Generally, when I use timeit from the interpreter prompt, I use "from
__main__ import *" as the setup code string. Then I can use all
currently defined global symbols directly :)
|
msg64838 - (view) |
Author: Peter Otten (peter.otten) * |
Date: 2008-04-02 06:42 |
Alexander, I'm fine with a more specific argument name. ns was what
the Timer already used internally.
Antoine, from __main__ import name1, ..., nameN works fine on the
command line, but inside a function you'd have to declare the names
you want to pass to the Timer as globals which I find a bit clumsy.
Apart from giving a syntax warning a star-import affects the generated
bytecode and produces the (slower) LOAD_NAME instead of LOAD_FAST.
|
msg64857 - (view) |
Author: Alexander Belopolsky (belopolsky) *  |
Date: 2008-04-02 14:01 |
On Wed, Apr 2, 2008 at 2:42 AM, Peter Otten <report@bugs.python.org> wrote:
> Alexander, I'm fine with a more specific argument name. ns was what
> the Timer already used internally.
>
Maybe it should be "locals" after all. It does not look like the
conflict with builtin locals() is an issue. Note that this is what
__import__ uses. I still recommend adding globals argument as well
for completeness and more accurate timings when timed code uses
globals.
|
msg80477 - (view) |
Author: David W. Lambert (LambertDW) |
Date: 2009-01-24 20:12 |
This note is simply a reminder that Antoine's 'from __main__ import *'
solution fails in python3. Also, resolution of this issue probably
could incorporate Issue1397474.
>>> import timeit
>>> timeit.timeit('None','from __main__ import *')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.0/timeit.py", line 227, in timeit
return Timer(stmt, setup, timer).timeit(number)
File "/usr/local/lib/python3.0/timeit.py", line 135, in __init__
code = compile(src, dummy_src_name, "exec")
File "<timeit-src>", line 2
SyntaxError: import * only allowed at module level
|
msg81215 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2009-02-05 15:07 |
Georg, why did you reassign this?
|
msg81267 - (view) |
Author: Georg Brandl (georg.brandl) *  |
Date: 2009-02-06 13:47 |
I'm sorry, this should have been another issue. Reassigning to you.
|
msg85689 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2009-04-07 06:47 |
See related discussion in issue 5441 and issue 1397474.
|
msg224933 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2014-08-06 13:35 |
Would still be nice to have something like this. The timeit module API is still crippled, especially now that "from __main__ import *" doesn't work in a function anymore.
|
msg225508 - (view) |
Author: Ben Roberts (roippi) * |
Date: 2014-08-18 21:37 |
Attached is a patch that adds a 'global' kwarg to the Timeit constructor, which does pretty much what it says on the tin: specifies a global namespace that exec() will use.
I originally had a 'locals' arg as well (to mirror the signature of eval/exec), but realized that the local vars I was passing to exec were not available to the inner function. Reason: the timeit module compiles/execs a *closure*, and closed-over variables and exec() simply do not play nicely. Possible workarounds were to munge locals() into the globals() dict, or to somehow inject the variables in the locals dict into the closure. I found neither of these options superior to simply not including a locals argument, for reasons of Least Surprise and maintainability.
Patch includes some basic tests and documentation. I am particularly uncomfortable with writing docs so those very likely need some polish.
|
msg225509 - (view) |
Author: Ben Roberts (roippi) * |
Date: 2014-08-18 22:17 |
Correction, the name of the argument is 'globals', not 'global'.
|
msg225621 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2014-08-21 23:21 |
Ben, thanks for the patch. Have you signed a contributor's agreement? You can find it at https://www.python.org/psf/contrib/contrib-form/
|
msg225627 - (view) |
Author: Ben Roberts (roippi) * |
Date: 2014-08-22 00:45 |
I did sign one right after I submitted the patch. Takes a few days for the asterisks to propagate I guess :)
|
msg225633 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2014-08-22 01:29 |
Ah, good. The patch looks fine to me, except that you should add "versionchanged" tags in the documentation for the added parameter.
|
msg225639 - (view) |
Author: Ben Roberts (roippi) * |
Date: 2014-08-22 03:01 |
Ah yes.
New patch improves the docs.
|
msg225724 - (view) |
Author: Roundup Robot (python-dev)  |
Date: 2014-08-23 03:24 |
New changeset e0f681f4ade3 by Antoine Pitrou in branch 'default':
Issue #2527: Add a *globals* argument to timeit functions, in order to override the globals namespace in which the timed code is executed.
http://hg.python.org/cpython/rev/e0f681f4ade3
|
msg225725 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2014-08-23 03:25 |
Thank you, Ben! Your patch is now pushed to the default branch.
|
msg225750 - (view) |
Author: Ben Roberts (roippi) * |
Date: 2014-08-23 15:28 |
Thanks Antoine. Cheers :-)
|
|
Date |
User |
Action |
Args |
2022-04-11 14:56:32 | admin | set | github: 46779 |
2014-08-23 15:28:53 | roippi | set | messages:
+ msg225750 |
2014-08-23 03:25:00 | pitrou | set | status: open -> closed resolution: fixed messages:
+ msg225725
stage: patch review -> resolved |
2014-08-23 03:24:22 | python-dev | set | nosy:
+ python-dev messages:
+ msg225724
|
2014-08-22 03:01:31 | roippi | set | files:
+ timeit_global_arg_v2.patch
messages:
+ msg225639 |
2014-08-22 01:29:55 | pitrou | set | messages:
+ msg225633 stage: needs patch -> patch review |
2014-08-22 00:45:44 | roippi | set | messages:
+ msg225627 |
2014-08-21 23:21:38 | pitrou | set | messages:
+ msg225621 |
2014-08-18 22:17:15 | roippi | set | messages:
+ msg225509 |
2014-08-18 21:37:32 | roippi | set | files:
+ timeit_global_arg.patch keywords:
+ patch messages:
+ msg225508
|
2014-08-17 19:50:46 | roippi | set | nosy:
+ roippi
|
2014-08-06 13:35:11 | pitrou | set | stage: patch review -> needs patch messages:
+ msg224933 versions:
+ Python 3.5, - Python 3.3 |
2011-11-19 14:12:50 | ezio.melotti | set | versions:
+ Python 3.3, - Python 3.2 |
2010-08-26 16:21:58 | BreamoreBoy | set | stage: patch review versions:
+ Python 3.2, - Python 3.1, Python 2.7 |
2009-04-07 06:47:44 | rhettinger | set | assignee: rhettinger -> messages:
+ msg85689 |
2009-04-03 14:24:03 | stefanv | set | nosy:
+ stefanv
|
2009-02-06 13:47:48 | georg.brandl | set | assignee: pitrou -> rhettinger messages:
+ msg81267 |
2009-02-05 15:07:46 | rhettinger | set | messages:
+ msg81215 |
2009-02-05 11:06:28 | georg.brandl | set | assignee: rhettinger -> pitrou |
2009-02-04 20:23:13 | rhettinger | set | priority: normal versions:
+ Python 3.1, Python 2.7, - Python 2.6 |
2009-01-27 05:17:21 | rhettinger | set | assignee: rhettinger nosy:
+ rhettinger |
2009-01-24 20:12:07 | LambertDW | set | nosy:
+ LambertDW messages:
+ msg80477 |
2009-01-23 14:32:10 | steven.daprano | set | nosy:
+ steven.daprano |
2008-04-02 14:01:25 | belopolsky | set | messages:
+ msg64857 |
2008-04-02 06:42:06 | peter.otten | set | messages:
+ msg64838 |
2008-04-01 18:50:35 | pitrou | set | nosy:
+ pitrou messages:
+ msg64816 |
2008-04-01 15:53:24 | belopolsky | set | messages:
+ msg64814 |
2008-04-01 15:48:04 | belopolsky | set | nosy:
+ belopolsky messages:
+ msg64812 |
2008-04-01 12:52:15 | benjamin.peterson | set | nosy:
+ georg.brandl |
2008-04-01 12:13:46 | peter.otten | create | |