Calling a function is faster than not calling it?

Christian Gollwitzer auriocus at gmx.de
Sun May 10 06:34:55 EDT 2015


Am 10.05.15 um 11:58 schrieb Steven D'Aprano:
> Why is calling a function faster than bypassing the function object and
> evaluating the code object itself? And not by a little, but by a lot?
>
> Here I have a file, eval_test.py:
>
> # === cut ===
> from timeit import Timer
>
> def func():
>      a = 2
>      b = 3
>      c = 4
>      return (a+b)*(a-b)/(a*c + b*c)
>
>
> code = func.__code__
> assert func() == eval(code)
>
> t1 = Timer("eval; func()", setup="from __main__ import func")
> t2 = Timer("eval(code)", setup="from __main__ import code")
>
> # Best of 10 trials.
> print (min(t1.repeat(repeat=10)))
> print (min(t2.repeat(repeat=10)))

what exactly does this mean, are you calling it 10 times? Are you sure 
hat is enaough to reach the granularity of your clock? A benchmark 
should last at least 100ms IMHO.

> # === cut ===
>
>
> Note that both tests include a name lookup for eval, so that as much as
> possible I am comparing the two pieces of code on an equal footing.
>
> Here are the results I get:
>
>
> [steve at ando ~]$ python2.7 eval_test.py
> 0.804041147232
> 1.74012994766
> [steve at ando ~]$ python3.3 eval_test.py
> 0.7233301624655724
> 1.7154695875942707
>
> Directly eval'ing the code object is easily more than twice as expensive
> than calling the function, but calling the function has to eval the code
> object. That suggests that the overhead of calling the function is
> negative, which is clearly ludicrous.
>
> I knew that calling eval() on a string was slow, as it has to parse and
> compile the source code into byte code before it can evaluate it, but this
> is pre-compiled and shouldn't have that overhead.

Does eval(code) lookup a,b and c in the scope of the eval, whereas in 
the func it is bound to locals and optimized out?

I've got no idea of Python's internals, just guessing.


	Christian



More information about the Python-list mailing list