Python编译器是否可能优化掉一些整数运算?

4
受到有关Python缓存小整数的这个问题的启发。
Python编译器是否可以在编译时将(0 - 6)替换为-6?下面的代码表明它没有这样做。如果不可能,为什么呢?我认为0-6的含义在运行时不会有所不同。
如果这是可能的,那么为什么CPython没有这样做呢?
# test_integers.py
def test_integers():
    print "-6 is -6 ?", -6 is -6 # True
    print "(0 - 6) is -6 ?", (0 - 6) is -6 # False

# import_test_integers.py
import test_integers
test_integers.test_integers()

如果这个问题与具体的实现有关,以下是我的Python详细信息:

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2

2
顺便说一句:这种类型的优化被称为“常量折叠”,(我不知道CPython是否执行它)。 - Laurence Gonsalves
1个回答

12

首先,你不应该使用 is 来比较整数值以检测优化。正如你在链接的问题中所解释的那样,这与任何事情都无关。如果您想知道对函数执行了哪些优化,请使用dis模块,在修复您的-1打字错误后,它会生成以下内容(在2.7.2中):

>>> import dis
>>> 
>>> def test_integers():
...     print "-6 is -6 ?", -6 is -6 # True
...     print "(0-6) is -6 ?", (0 - 6) is -6 # False
... 
>>> dis.dis(test_integers)
  2           0 LOAD_CONST               1 ('-6 is -6 ?')
              3 PRINT_ITEM          
              4 LOAD_CONST               2 (-6)
              7 LOAD_CONST               2 (-6)
             10 COMPARE_OP               8 (is)
             13 PRINT_ITEM          
             14 PRINT_NEWLINE       

  3          15 LOAD_CONST               3 ('(0-6) is -6 ?')
             18 PRINT_ITEM          
             19 LOAD_CONST               6 (-6)
             22 LOAD_CONST               2 (-6)
             25 COMPARE_OP               8 (is)
             28 PRINT_ITEM          
             29 PRINT_NEWLINE       
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE        

你会看到减法实际上已经被优化掉了。你还可以看到其他一些情况:

>>> def f():
...     x = 1+2
...     x = 2-3
...     x = 3*4
...     x = 4/5
...     x = 5**6
... 
>>> dis.dis(f)
  2           0 LOAD_CONST               7 (3)
              3 STORE_FAST               0 (x)

  3           6 LOAD_CONST               8 (-1)
              9 STORE_FAST               0 (x)

  4          12 LOAD_CONST               9 (12)
             15 STORE_FAST               0 (x)

  5          18 LOAD_CONST               4 (4)
             21 LOAD_CONST               5 (5)
             24 BINARY_DIVIDE       
             25 STORE_FAST               0 (x)

  6          28 LOAD_CONST              10 (15625)
             31 STORE_FAST               0 (x)
             34 LOAD_CONST               0 (None)
             37 RETURN_VALUE        

糟糕,我正要发布类似的内容。很好的回答。+1 - mgilson
已更正打字错误,谢谢。仍在消化您的其余回答。 - RoundTower
这个回答完美地解答了我的问题,但是我对LOAD_CONSTco_consts的工作原理更加困惑了。如果我找不到或者无法弄清楚答案,我会发布跟进问题的。 - RoundTower
是的,我希望我会接受它 - 只是暂时等待,以防有人发表更好的答案。 - RoundTower

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接