2010-11-29 2 views
14

Rich Hickey и другие упоминали, что Clojure не получит существенного улучшения от предстоящего invokeDynamic, запланированного для JVM 7 или 8, но увидит прирост производительности от рекурсии хвоста.Улучшения Clojure JVM 7/8

Will хвостовая рекурсия оказывает никакого влияния на

(fn [...] (recur ...)) 

или

(loop [...] (recur ...)) 

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

ответ

17

Non ваши примеры получите быстрее, потому что если вы используете recur вы уже сказать компилятору, что у вас есть хвост рекурсивной функции, и это позволяет компилятору генерировать байт-код, который использует goto (как обычный императивный петли)

Есть некоторые преимущества, если JVM получает оптимизацию хвостового вызова.

Вы не придется использовать повторялись больше (если вы не хотите), так что вы можете написать функцию, как это (хвост рекурсивная функция)

(defn testfn [n] (when (not= 1000 n) (testfn n))) 

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

(defn testfn [n] (when (not= 1000 n) (recur n))) 

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

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

(defn even [n] (if (zero? n) true (odd? (dec n))) 
(defn odd [n] (if (zero? n) false (even (dec n))) 

Если вы попробуете это с большим количеством, знаете, что вы взорвите стек, но с оптимизацией вызывного хвоста вы не будете.

I have on немного дополнение левый. Существует функция называется trampoline, что позволит вам сделать это уже (с небольшим изменением в стиле программирования и некоторые накладные расходы) Вместо объяснения trampoline я отсылаю вас к блогу, который делает именно то, что:

http://pramode.net/clojure/2010/05/08/clojure-trampoline/

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