为什么这两个功能不同?

时间:2022-04-03 16:51:56

Take a look at this:

看看这个:

>>> def f():
...     return (2+3)*4
... 
>>> dis(f)
  2           0 LOAD_CONST               5 (20)
              3 RETURN_VALUE  

Evidently, the compiler has pre-evaluated (2+3)*4, which makes sense.

显然,编译器已预先评估(2 + 3)* 4,这是有道理的。

Now, if I simply change the order of the operands of *:

现在,如果我只是改变*的操作数的顺序:

>>> def f():
...     return 4*(2+3)
... 
>>> dis(f)
  2           0 LOAD_CONST               1 (4)
              3 LOAD_CONST               4 (5)
              6 BINARY_MULTIPLY     
              7 RETURN_VALUE  

The expression is no longer fully pre-evaluated! What is the reason for this? I am using CPython 2.7.3.

表达式不再完全预先评估!这是什么原因?我正在使用CPython 2.7.3。

2 个解决方案

#1


9  

In the first case the unoptimized code is LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY and in the second case it's LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY. The pattern matcher in fold_binops_on_constants() must handle the first ADD ok (replacing LOAD LOAD ADD with LOAD) and then follows on to do the same thing to MULTIPLY. In the second case by the time the ADD (now the second argument to MULTIPLY instead of the first) is turned into a constant the scanner is too far ahead to see L L M (when the "cursor" was on LOAD 4 it didn't look like a L L M yet).

在第一种情况下,未优化的代码是LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY,在第二种情况下,它是LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY。 fold_binops_on_constants()中的模式匹配器必须处理第一个ADD ok(用LOAD替换LOAD LOAD ADD),然后继续对MULTIPLY执行相同的操作。在第二种情况下,当ADD(现在是MULTIPLY的第二个参数而不是第一个参数)变为常量时,扫描仪太远而无法看到LLM(当“光标”在LOAD 4上时它看起来不像像LLM一样)。

#2


5  

Looks like this issue was patched in Python 3.3, as can be seen here.

看起来这个问题已在Python 3.3中修补,如此处所示。

>>> def f():
...     return (2+3)*4
... 
>>> dis(f)
  2           0 LOAD_CONST               5 (20)
              3 RETURN_VALUE  
>>> def f():
...     return 4*(2+3)
... 
>>> dis(f)
  2           0 LOAD_CONST               5 (20)
              3 RETURN_VALUE 

#1


9  

In the first case the unoptimized code is LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY and in the second case it's LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY. The pattern matcher in fold_binops_on_constants() must handle the first ADD ok (replacing LOAD LOAD ADD with LOAD) and then follows on to do the same thing to MULTIPLY. In the second case by the time the ADD (now the second argument to MULTIPLY instead of the first) is turned into a constant the scanner is too far ahead to see L L M (when the "cursor" was on LOAD 4 it didn't look like a L L M yet).

在第一种情况下,未优化的代码是LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY,在第二种情况下,它是LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY。 fold_binops_on_constants()中的模式匹配器必须处理第一个ADD ok(用LOAD替换LOAD LOAD ADD),然后继续对MULTIPLY执行相同的操作。在第二种情况下,当ADD(现在是MULTIPLY的第二个参数而不是第一个参数)变为常量时,扫描仪太远而无法看到LLM(当“光标”在LOAD 4上时它看起来不像像LLM一样)。

#2


5  

Looks like this issue was patched in Python 3.3, as can be seen here.

看起来这个问题已在Python 3.3中修补,如此处所示。

>>> def f():
...     return (2+3)*4
... 
>>> dis(f)
  2           0 LOAD_CONST               5 (20)
              3 RETURN_VALUE  
>>> def f():
...     return 4*(2+3)
... 
>>> dis(f)
  2           0 LOAD_CONST               5 (20)
              3 RETURN_VALUE