4

私はいつもPythonインタープリターが-Oフラグなしで最適化を行わないと思っていましたが、以下は少し奇妙です:

>>> def foo():
...     print '%s' % 'Hello world'
...
>>> from dis import dis 
>>> dis(foo)
  2           0 LOAD_CONST               3 ('Hello world')
              3 PRINT_ITEM          
              4 PRINT_NEWLINE       
              5 LOAD_CONST               0 (None)
              8 RETURN_VALUE        

インタプリタが2つの文字列定数のモジュロでフォールディングを行っているように見えます。ただし、変数を追加すると、最適化されていない結果が得られます。

>>> def foo():
...     s = 'Hello world!'
...     print '%s' % s
... 
>>> dis(foo)
  2           0 LOAD_CONST               1 ('Hello world!')
              3 STORE_FAST               0 (s)

  3           6 LOAD_CONST               2 ('%s')
              9 LOAD_FAST                0 (s)
             12 BINARY_MODULO       
             13 PRINT_ITEM          
             14 PRINT_NEWLINE       
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE        

Pythonは-Oフラグなしでどのような最適化を行いますか?そして、それらを無効にする方法はありますか?最適化されていないPythonバイトコードがどのように表示されるかを確認したいと思います。実稼働タイプの環境でこれを行う予定はありません。

4

2 に答える 2

9

はい、定数畳み込みを行います。簡単な例を次に示します。

>>> def f(): return 23+100
... 
>>> dis.dis(f)
  1           0 LOAD_CONST               3 (123)
              3 RETURN_VALUE        
>>> 

これをブロックする方法はありません(ソースを変更する場合を除く)。

編集:すべての最適化フローについては、peephole.cを参照してください。これは、「ソースを変更」するのにおそらく最も便利な場所です。

if (codelen > 32700)

if (codelen > 0)

すべての最適化が無条件に無効になっていることを確認します。

于 2010-01-10T20:31:52.820 に答える
0

一定の折りたたみを回避する方法は次のとおりです。

>>> dis.dis(lambda: (3,)[0]+(4,)[0])
  1           0 LOAD_CONST               5 (3)
              3 LOAD_CONST               7 (4)
              6 BINARY_ADD          
              7 RETURN_VALUE        

ただし、追加の定数に注意してください。

>>> (lambda: (3,)[0]+(4,0)[0]).func_code.co_consts
(None, 3, 0, 4, (3,), 3, (4, 0), 4)
于 2014-04-06T16:26:53.510 に答える