26

これを見てください:

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

明らかに、コンパイラは を事前に評価して(2+3)*4おり、これは理にかなっています。

ここで、 のオペランドの順序を単純に変更すると、次のようになります*

>>> 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  

式は完全に事前評価されていません! これの理由は何ですか?私は CPython 2.7.3 を使用しています。

4

2 に答える 2

9

最初のケースでは、最適化されていないコードはLOAD 2 LOAD 3 ADD LOAD 4 MULTIPLYであり、2 番目のケースではLOAD 4 LOAD 2 LOAD 3 ADD MULTIPLYです。のパターン マッチャーはfold_binops_on_constants()、最初の ok を処理し(ADDを に置き換え)、続いて に対して同じことを行う必要があります。2 番目のケースでは、(最初の引数の代わりに の 2 番目の引数) が定数に変わるまでに、スキャナーが先に進みすぎて見えなくなります (「カーソル」がオンになっているときは、まだ のようには見えませんでした)。LOAD LOAD ADDLOADMULTIPLYADDMULTIPLYL L MLOAD 4L L M

于 2013-07-23T01:32:04.903 に答える
5

ここで見られるように、この問題は 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 
于 2013-07-25T14:56:10.620 に答える