Чем пришлось бы пожертвовать jvm, чтобы реализовать оптимизацию конечных вызовов?

StackOverflow https://stackoverflow.com/questions/1006596

Вопрос

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

http://lambda-the-ultimate.org/node/2547

Было сказано, что для внедрения TCO в Python пришлось бы пожертвовать

  • дампы трассировки стека и
  • регулярность отладки.

Объясните мне, что такого особенного в оптимизации хвостовых вызовов и зачем это нужно Python

Должны ли быть принесены такие же жертвы для совместной реализации TCO?Пришлось бы пожертвовать чем-нибудь еще?

Это было полезно?

Решение

Несмотря на отличие (в том, что инструкции il уже существовали), стоит отметить дополнительные усилия, приложенные .Net 64-битная команда JIT пришлось пройти до конца, чтобы уважать все вызовы "хвоста".

Я обращаюсь, в частности, к комментарию:

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

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

Учитывая, что в обстоятельствах, когда была запрошена оптимизация хвостового вызова, JIT должен предположить, что это требуемый чтобы избежать переполнения стека, это не то, что можно просто отключить в отладочных сборках.От них мало толку для отладки, если они выходят из строя до того, как вы переходите к интересной части."Оптимизация" на самом деле является постоянной функцией и проблемой для трассировок стека, на которые она влияет.

Стоит отметить, что любая оптимизация, которая позволяет избежать создания реального фрейма стека при выполнении операции, которую программист концептуально описывает / понимает как операцию стека (например, вызов функции), по своей сути вызовет разрыв между тем, что представляется пользователю при отладке / предоставлении трассировки стека, и реальностью.
Это неизбежно, поскольку код, описывающий операцию, становится все более и более отделенным от механики конечного автомата, выполняющего операцию.

Другие советы

Работа - это сейчас идет работа чтобы добавить хвостовые вызовы в JVM.Там есть вики - страница обсуждаем некоторые детали.

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

Также стоит интересно отметить, что Clojure имеет не требующую стека функцию "recur", позволяющую обойти это ограничение в текущих версиях JVM.

Пример:

(defn triangle [n accumulator] 
  (if 
    (<= n 0)  
      accumulator
      (recur (dec n) (+ n accumulator))))

(triangle 1000000 0)

=> 500000500000     (note stack does not explode here!)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top