views:

44

answers:

3

Given the following:

def foo():
    x = a_method_returning_a_long_list()
    y = a_method_which_filters_a_list(x)
    return y

will Python's bytecode compiler keep x & y in memory, or is it clever enough to reduce it to the following?

def foo():
   return a_method_which_filters_a_list(a_method_returning_a_long_list())
A: 

I'm not certain, but I would guess it would keep them in memory, for 2 reasons. First, it's probably more effort than its worth to do that. There wouldn't be a huge performance change either way. And second, the variables x and y are probably themselves taking up memory (in the form of pointers/references), which the compiler would not touch, due to the explicit nature of the assignment.

Roadrunner-EX
+2  A: 
In [1]: import dis

In [2]: def f():
   ...:     x = f1()
   ...:     y = f2(x)
   ...:     return y
   ...: 

In [3]: dis.dis(f)
  2           0 LOAD_GLOBAL              0 (f1)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (x)

  3           9 LOAD_GLOBAL              1 (f2)
             12 LOAD_FAST                0 (x)
             15 CALL_FUNCTION            1
             18 STORE_FAST               1 (y)

  4          21 LOAD_FAST                1 (y)
             24 RETURN_VALUE        

So it looks like both variables are held separately.

wRAR
+3  A: 

It keeps x and y in memory:

import dis
dis.dis(foo)
  2           0 LOAD_GLOBAL              0 (a_method_returning_a_long_list)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (x)

  3           9 LOAD_GLOBAL              1 (a_method_which_filters_a_list)
             12 LOAD_FAST                0 (x)
             15 CALL_FUNCTION            1
             18 STORE_FAST               1 (y)

  4          21 LOAD_FAST                1 (y)
             24 RETURN_VALUE

The whole operation is quite efficient, as it is done using the LOAD_FAST and STORE_FAST codes.

As Roadrunner-EX remarks in one of the comments, the amount of memory used by your two versions of foo is basically the same, as x and y are just references (i.e., pointers) to the results.

pberkes