Search code examples
pythonvariablesvariable-assignmentassign

Time to assign a variable in Python


Suppose I have the following in a really tight loop:

a = func(x)
b = func2(a)

The variable a is not used anywhere else.

Does Python automatically compile away the assignment to a, or does it take the time to do the variable assignment every time? In other words, is this code identical, or is it marginally faster due to the lack of assigning to a?

b = func2(func(x))

Is the behavior the same for Python2.7 vs Python3?


Solution

  • So using the very fun dis module we can look into the actual bytecode that is generated from the python code you provided. To keep things simple I have replaced func and func2 with builtin functions (int and float).

    So our source looks like this:

    def assign():
        a = int()
        b = float(a)
    

    Versus a simplified version:

    def simple():
        b = float(int())
    

    And then starting with the cpython 2.7 interpretter, we can see the bytecodes generated from the assign function:

    dis.dis(assign)
      2           0 LOAD_GLOBAL              0 (int)
                  3 CALL_FUNCTION            0
                  6 STORE_FAST               0 (a)
    
      3           9 LOAD_GLOBAL              1 (float)
                 12 LOAD_FAST                0 (a)
                 15 CALL_FUNCTION            1
                 18 STORE_FAST               1 (b)
                 21 LOAD_CONST               0 (None)
                 24 RETURN_VALUE
    

    As you can see there is no peephole optimization to remove the unnecessary intermediate variable, which results in an additional 2 instructions (STORE_FAST a, LOAD_FAST a) when compared against the bytecodes for the simplified `simple method:

    dis.dis(simple)
      2           0 LOAD_GLOBAL              0 (float)
                  3 LOAD_GLOBAL              1 (int)
                  6 CALL_FUNCTION            0
                  9 CALL_FUNCTION            1
                 12 STORE_FAST               0 (b)
                 15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE
    

    This is the same for the CPython interpreter for Python 3.5, and for the pypy interpreter for Python 2.7.