Bo Peng wrote:
Exec is slow since compiling the string and calls to globals() use a lot of time. The last one is most elegant but __getattr__ and __setattr__ are costly. The 'evil hack' solution is good since accessing x and y takes no additional time.
Previous comparison was not completely fair since I could pre-compile fun2 and I used indirect __setattr__. Here is the new one:
>>> # solution two: use exec
... def makeFunction(funcStr, name):
... code = compile(funcStr, name, 'exec')
... def f(d):
... exec code in d
... return f
...
>>> def fun2(d):
... myfun = makeFunction('z = x + y', 'myfun')
... for i in xrange(0,N):
... myfun(d)
... del d['__builtins__']
You are still including the compile overhead in fun2. If you want to see how fast the compiled code is you should take the definition of myfun out of fun2:
myfun = makeFunction('z = x + y', 'myfun') def fun2(d): for i in xrange(0,N): myfun(d) del d['__builtins__']
Kent
I assumed that most of the time will be spent on N times execution of myfunc.
>>> myfun = makeFunction('z = x + y', 'myfun') >>> def fun2(d): ... # myfun = makeFunction('z = x + y', 'myfun') ... for i in xrange(0,N): ... myfun(d) ... del d['__builtins__'] >>> def fun21(d): ... myfun = makeFunction('z = x + y', 'myfun') ... for i in xrange(0,N): ... myfun(d) ... del d['__builtins__']
>>> profile.run('fun2(a)') 200003 function calls in 1.930 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.930 1.930 <string>:1(?) 100000 0.460 0.000 0.460 0.000 myfun:1(?) 1 0.000 0.000 1.930 1.930 profile:0(fun2(a)) 0 0.000 0.000 profile:0(profiler) 100000 0.980 0.000 1.440 0.000 python-162616Io.py:4(f) 1 0.490 0.490 1.930 1.930 python-16261Ud0.py:1(fun2)
>>> profile.run('fun21(a)') 200004 function calls in 1.920 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.920 1.920 <string>:1(?)
100000 0.390 0.000 0.390 0.000 myfun:1(?)
1 0.000 0.000 1.920 1.920 profile:0(fun21(a))
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 python-162616Io.py:2(makeFunction)
100000 0.930 0.000 1.320 0.000 python-162616Io.py:4(f)
1 0.600 0.600 1.920 1.920 python-16261huu.py:1(fun21)
--
http://mail.python.org/mailman/listinfo/python-list