Why doesn't Python optimize away temporary variables?

帅比萌擦擦* 提交于 2019-12-22 08:17:38

问题


Fowler's Extract Variable refactoring method, formerly Introduce Explaining Variable, says use a temporary variable to make code clearer for humans. The idea is to elucidate complex code by introducing an otherwise unneeded local variable, and naming that variable for exposition purposes. It also advocates this kind of explaining over comments.. Other languages optimize away temporary variables so there's no cost in time or space resources. Why doesn't Python do this?

In [3]: def multiple_of_six_fat(n):
   ...:     multiple_of_two = n%2 == 0
   ...:     multiple_of_three = n%3 == 0
   ...:     return multiple_of_two and multiple_of_three
   ...:

In [4]: def multiple_of_six_lean(n):
   ...:     return n%2 == 0 and n%3 == 0
   ...:
In [5]: import dis

In [6]: dis.dis(multiple_of_six_fat)
  2           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (2)
              6 BINARY_MODULO
              7 LOAD_CONST               2 (0)
             10 COMPARE_OP               2 (==)
             13 STORE_FAST               1 (multiple_of_two)

  3          16 LOAD_FAST                0 (n)
             19 LOAD_CONST               3 (3)
             22 BINARY_MODULO
             23 LOAD_CONST               2 (0)
             26 COMPARE_OP               2 (==)
             29 STORE_FAST               2 (multiple_of_three)

  4          32 LOAD_FAST                1 (multiple_of_two)
             35 JUMP_IF_FALSE_OR_POP    41
             38 LOAD_FAST                2 (multiple_of_three)
        >>   41 RETURN_VALUE

In [7]: dis.dis(multiple_of_six_lean)
  2           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (2)
              6 BINARY_MODULO
              7 LOAD_CONST               2 (0)
             10 COMPARE_OP               2 (==)
             13 JUMP_IF_FALSE_OR_POP    29
             16 LOAD_FAST                0 (n)
             19 LOAD_CONST               3 (3)
             22 BINARY_MODULO
             23 LOAD_CONST               2 (0)
             26 COMPARE_OP               2 (==)
        >>   29 RETURN_VALUE

回答1:


Because Python is a highly dynamic language, and references can influence behaviour.

Compare the following, for example:

>>> id(object()) == id(object())
True
>>> ob1 = object()
>>> ob2 = object()
>>> id(ob1) == id(ob2)
False

Had Python 'optimised' the ob1 and ob2 variables away, behaviour would have changed.

Python object lifetime is governed by reference counts. Add weak references into the mix plus threading, and you'll see that optimising away variables (even local ones) can lead to undesirable behaviour changes.

Besides, in Python, removing those variables would hardly have changed anything from a performance perspective. The local namespace is already highly optimised (values are looked up by index in an array); if you are worried about the speed of dereferencing local variables, you are using the wrong programming language for that time critical section of your project.




回答2:


Issue 2181 (optimize out local variables at end of function) has some interesting points:

  • It can make debugging harder since the symbols no longer exist. Guido says only do it for -O.
  • Might break some usages of inspect or sys._getframe().
  • Changes the lifetime of objects. For example myfunc in the following example might fail after optimization because at the moment Python guarantees that the file object is not closed before the function exits. (bad style, but still)

    def myfunc():
        f = open('somewhere', 'r')
        fd = f.fileno()
        return os.fstat(fd)
    

    cannot be rewritten as:

    def bogus():
        fd = open('somewhere', 'r').fileno()
        # the file is auto-closed here and fd becomes invalid
        return os.fstat(fd)
    
  • A core developer says that "it is unlikely to give any speedup in real-world code, I don't think we should add complexity to the compiler."



来源:https://stackoverflow.com/questions/28993557/why-doesnt-python-optimize-away-temporary-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!