2010-11-29 6 views
14

Rich Hickey und andere haben erwähnt, dass Clojure keine signifikante Verbesserung gegenüber dem für JVM 7 oder 8 geplanten invokeDynamic erzielen wird, aber einen Leistungsgewinn durch Tail-Rekursion sehen wird.Clojure JVM 7/8 Verbesserungen

Will Endrekursion haben keine Auswirkungen auf

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

oder

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

ich nicht erwarten, dass sie schneller bekommen, da der Compiler wahrscheinlich schon Schleifenstrukturen erzeugt.

Antwort

17

Nicht Ihre Beispiele werden schneller, weil, wenn Sie verwenden recur Sie bereits den Compiler sagen, dass Sie einen Schwanz rekursive Funktion haben und dies ermöglicht es dem Compiler-Byte-Code zu generieren, die goto (wie ein normaler Imperativ loop) verwendet

Es gibt natürlich einige Vorteile, wenn die JVM die Tail Call Optimierung erhält.

Sie gewohnt haben, um mehr wiederholen zu verwenden (wenn Sie nicht wollen), so können Sie eine Funktion wie diese (a Schwanz rekursive Funktion)

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

schreiben Nowdays die JVM nicht in der Lage ist zu erkennen, Schwanzrekursion. Mit dem Zusatz von Endrekursion Optimierung der JVM der Lage, die Funktion siehe oben, als ob Sie das geschrieben hatten (und daher zwingend notwendig, Schleife Geschwindigkeit zu erhalten):

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

Damit nicht so groß von einer Verbesserung, aber es ist ein anderes Fall, wo die Tail-Call-Optimierung wirklich großartig ist.

Wenn Sie Funktionen haben, die sich gegenseitig aufrufen (manchmal sogar mehr als zwei) und die nicht auf dem Stack halten müssen (sind rekursiv), kann die JVM sie optimieren. Dies ist jetzt nicht möglich, da Sie recur nicht sagen können, um zu einer anderen Funktion zu springen. Hier ist ein Beispiel.

Wenn Sie dies mit einer großen Anzahl versuchen, wissen Sie, dass Sie den Stapel blasen werden, aber mit Tail-Call-Optimierung werden Sie nicht.

Ich habe auf wenig Ergänzung übrig. Es gibt eine Funktion trampoline genannt, mit denen Sie tun dies bereits (mit einer kleinen Änderung im Programmierstil und etwas Overhead) Statt trampoline zu erklären, ich werde Sie in ein Blog verweisen, die genau das tut:

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

Verwandte Themen