Function definition in Python takes a lot of time

It is the peephole optimizer:

https://github.com/python/cpython/blob/2.7/Python/peephole.c#L88

See in particular lines 104-106:

case BINARY_POWER:
    newconst = PyNumber_Power(v, w, Py_None);
    break;

The intention is to speed up runtime execution of the function, trading-off for a slower definition time when the module is imported. The idea is you only need to compile the code for the function once, but you may need to call it many times, and the outcome of an exponentiation binop for two constants is not going to change so it needn't be recomputed every time.

Note: In Python 3, constant folding has moved into the new AST optimizer in ast_opt.c, peephole.c is gone. The code now has safeguards in place to prevent the overly-eager optimizations that could cause as a slow or memory-hungry parse/compile step as shown in this question.


Let's try a more reasonable number:

>>> def f():
...    p=123**45
... 

If you use dis to view the byte codes, you can see that the value for p is being defined BEFORE the function is called:

>>> import dis
>>> dis.dis(f)
  2           0 LOAD_CONST               3 (11110408185131956285910790587176451918559153212268021823629073199866111001242743283966127048043)
              3 STORE_FAST               0 (p)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE

This feature of the interpreter is called constant folding (see here for some nice information). There exist several issues addressing even too aggressive constant folding. Similar issues can arise for memory as well, where a lot of memory is allocated and directly thrown away again (see here).