2010-01-10 3 views
4

Я всегда считал, что интерпретатор Python не сделал ни одного оптимизаций без -O флага, но следующее немного странный:Какие оптимизации делает 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   

Похоже, что интерпретатор делают некоторое складывание по модулю два строковых констант , Если добавить переменную в хотя, это дает неоптимизированная результат:

>>> 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. Я не планирую делать это в любой производственной среде.

ответ

9

Да, это сделать постоянную складывание, вот простой пример:

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

Ни в коем случае блокировать это (за исключением изменения источников) AFAIK.

Редактировать: для всего потока оптимизации см. peephole.c - это, вероятно, самое удобное место для «смены источников», например. изменение линии 320 от

if (codelen > 32700) 

в

if (codelen > 0) 

, чтобы убедиться, что все оптимизации безоговорочно отключены.

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) 
Смежные вопросы