Python bytecode compiler; removes unnecessary variables?
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())
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.
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.
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.
精彩评论