Calling a function is faster than not calling it?

BartC bc at freeuk.com
Mon May 11 11:01:49 EDT 2015


On 11/05/2015 15:12, Skip Montanaro wrote:
>
> On Mon, May 11, 2015 at 4:50 AM, BartC <bc at freeuk.com
> <mailto:bc at freeuk.com>> wrote:
>
>     You just seem surprised that using eval() to do this is slower than
>     a direct call.
>
>
> Well, it is surprising. Most uses of eval() are to evaluate Python
> expressions in string form. That I expect to be quite slow, given the
> parsing+byte compilation overhead. I wouldn't expect eval()ing a code
> object to be all that different than calling the function containing the
> code object.

func() (when the call is itself inside a function) has this bytecode:

  11           0 LOAD_GLOBAL              0 (func)
               3 CALL_FUNCTION            0
               6 POP_TOP
               7 LOAD_CONST               0 (None)
              10 RETURN_VALUE


eval(code) (when this is also inside a function, and code is local) has 
this bytecode:

  16           6 LOAD_GLOBAL              0 (eval)
               9 LOAD_FAST                0 (code)
              12 CALL_FUNCTION            1
              15 POP_TOP
              16 LOAD_CONST               0 (None)
              19 RETURN_VALUE


So eval() seems to be just as much a function call as func() is. Except:

(1) It has an extra argument ('code'), in addition to any normal 
arguments of func (0 in this case)

(2) Before it can do whatever func() does, in has to /get there/ first. 
And that can code presumably has a similarly indirect path to return to 
the point to where eval() was called. So there is extra code inside eval 
to deal with this (as well as check whether a string has been passed). 
That code must be the extra overhead.

So it seems clear to me that the eval method has to do everything that 
calling func() has to do, and then some.

(That doesn't necessarily mean it would be slower; whatever goes on 
inside could well have been made less efficient for a direct call than 
for an indirect one via eval. But the results suggest it is slower using 
eval. And it isn't really surprising.)

-- 
Bartc



More information about the Python-list mailing list