2013-09-24 2 views
3

Похоже, что python (2.6) не может оптимизировать эту простую временную переменную 'a'?Может ли Python оптимизировать этот простой вызов переменной?

Я использую для назначения локальной переменной некоторому коду, чтобы уменьшить длину строки.

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

from dis import dis 

def f(func): 
    func() 

def functioncall(): 
    print ' => function called' 

def unoptimized(): 
    print 'in unoptimized' 
    a = functioncall 
    f(func=a) 

def optimized(): 
    print 'in optimized' 
    f(func=functioncall) 

unoptimized() 
optimized() 

print 'dis(unoptimized)' 
dis(unoptimized) 
print 'dis(optimized)' 
dis(optimized) 

Выход:

in unoptimized 
=> function called 
in optimized 
=> function called 
dis(unoptimized) 
10   0 LOAD_CONST    1 ('in unoptimized') 
       3 PRINT_ITEM 
       4 PRINT_NEWLINE 

11   5 LOAD_GLOBAL    0 (functioncall) 
       8 STORE_FAST    0 (a) 

12   11 LOAD_GLOBAL    1 (f) 
      14 LOAD_CONST    2 ('func') 
      17 LOAD_FAST    0 (a) 
      20 CALL_FUNCTION   256 
      23 POP_TOP 
      24 LOAD_CONST    0 (None) 
      27 RETURN_VALUE 
dis(optimized) 
15   0 LOAD_CONST    1 ('in optimized') 
       3 PRINT_ITEM 
       4 PRINT_NEWLINE 

16   5 LOAD_GLOBAL    0 (f) 
       8 LOAD_CONST    2 ('func') 
      11 LOAD_GLOBAL    1 (functioncall) 
      14 CALL_FUNCTION   256 
      17 POP_TOP 
      18 LOAD_CONST    0 (None) 
      21 RETURN_VALUE 

Почему он не может удалить это автоматически?

11   5 LOAD_GLOBAL    0 (functioncall) 
       8 STORE_FAST    0 (a) 

ответ

5

CPython, стандартная реализация Python, не делает большой оптимизации; это довольно простой перевод исходного кода на байт-код. Есть несколько оптимизаций (исключение или подъем кода под if __debug__, являющийся одним из них), и я полагаю, что есть оптимизатор подглядываний, но я предполагаю, что этап компиляции должен быть достаточно быстрым, что не позволяет делать много анализа.

Поддержание работоспособности также кажется ключевым для разработчиков Python. Вот a thread from 2009, в котором рассматривается патч для удаления мертвого кода, а затем отклоняется, поскольку это сделает компилятор менее ремонтопригодным.

Если вам нужна высокая производительность, вы хотите что-то другое, кроме CPython; возможно, PyPy поможет. Python в целом оптимизирован для экономии времени программиста, а не времени исполнения. Если вы не хотите, чтобы в вашем байт-коде отсутствовал код, не помещайте его в исходный код. :-)

+0

Я мог ошибаться, но я думал, что PyPy действительно делает такую ​​оптимизацию при потере расширений C. –

+2

Вы должны вернуть это обратно: «Если вы не хотите, чтобы в вашем байт-коде не был мертвый код, не помещайте его в исходный код». :) – wflynny

+0

:-) Готово, почему бы и нет! Я взял его, потому что технически это не мертвый код, он фактически выполнен. – kindall

1

В принципе, интерпретатор Python мог бы оптимизировать это.

На практике люди программируют на Python, потому что быстро писать код в нем, а не потому, что написанный с ним код выполняется быстро. Поэтому в этом конкретном случае программист должен оптимизировать.

0

В python исходный код не исчезает полностью - оператор def является исполняемым оператором, который создает объект функции. Вы спрашиваете, почему python не умно делает что-то другое, чем то, что было предложено во имя оптимизации.

Такая оптимизация достаточно проста для выполнения вручную, при необходимости, с помощью инструмента для линта. Не стоит вводить неожиданные последствия, которые могут возникнуть. В конце концов, точка python проста в чтении и записи.

+0

Я не согласен с вами. Это очень простая оптимизация, которую компилятор уже делает, почему бы не сделать это? Его легко обнаружить, легко реализовать. – Gaetan

+0

@Gaetan Нигде я не говорю, что это сложно. Это проблематично. – Marcin

+0

Проблема не означает, что это не должно быть сделано. Это явно поток в языке. Большую часть времени, оптимизируя код, он делает его менее читаемым, я предпочитаю знать ситуацию, в которой код будет оптимизирован, и, таким образом, писать более читаемый код, чем делать некоторые kung foo в моем коде. Я довольно хорошо знаю оптимизацию на C++, и я настолько разочарован интерпретатором python по этому вопросу. Это и плохая многопоточная модель на python – Gaetan

0

TL; DR: это особенность.

Я считаю, что этот тип оптимизации должен не быть сделан по умолчанию потому что y=g(f(x)) является не эквивалентно a=f(x) ; y=g(a): Python имеет побочные эффекты, которые здесь конструкция.

Локальные пространства имен предназначены для доступа к самому Python: они имеют четко определенный API. Документация функции eval и оператора exec (Python> = 2.4) гласит: «Если предоставлено, locals могут быть любым объектом сопоставления».

Одно из возможных приложений - написать отладчик Python в Python.Я могу подклассом dict, чтобы каждое чтение/запись в локальном пространстве имен вызывало некоторое событие GUI; Теперь я могу наблюдать промежуточный результат a между a=f(x) и y=g(a). Без этой возможности мне пришлось бы проверять виртуальный стек CPython или все, что они используют в любой другой реализации Python.

Помимо отладки, я вижу другие возможные возможности использования этой функции. Я мог бы представить себе внедрение Python в движок видеоигр. Дизайнеры, отвечающие за историю, квесты, персонажи, события, все это, здесь, чтобы превратить свое воображение в игровой контент, а не писать код. Чтобы сделать их жизнь проще, я мог запускать их скрипты с помощью специального локального пространства имен, которое поставляется с некоторыми предварительно загруженными и/или значениями в реальном времени. Имена my_hp и their_hp всегда будут возвращать/устанавливать текущее количество точек попадания двух существ, участвующих в событии «атака», вызвавшем сценарий. Моим дизайнерам не нужно было бы печатать self. все время (и они даже не знали бы о классах и объектах). В некотором смысле, my_hp будет действовать как глобальный или дескриптор, за исключением того, что он будет локальным для существа и не требует явного исключения класса/экземпляра. Это намного проще реализовать таким образом, чем пытаться проанализировать их сценарий и угадать, когда мы должны добавить self перед материалом.

Одним словом: вы никогда не знаете, что виртуальная машина будет делать с вашим кодом, поэтому все, что может показаться идентичным, не всегда так.

Смежные вопросы