質問

リッチなヒッキーなどは、Clojureが今後から大幅に改善されないと述べています invokeDynamic JVM 7または8では計画されていますが、テールの再帰からパフォーマンスが向上します。

尾の再帰は何らかの影響を与えます

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

また

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

コンパイラーはおそらくすでにループ構造を生成しているため、彼らがより速くなるとは思っていません。

役に立ちましたか?

解決

あなたが使用する場合、あなたの例はより速くなります recur 既にコンパイラに、テール再帰機能があることを伝え、これによりコンパイラが使用するバイトコードを生成できることを伝えます goto (通常の命令ループのように)

JVMがテールコールの最適化を取得した場合、コース外の利点があります。

もう繰り返し使用する必要はありません(したくない場合)。

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

現在、JVMは尾の再帰を検出できません。テールコールの最適化を追加すると、JVMはこれを書いたかのように上記の関数を見ることができます(したがって、必須ループ速度を取得します):

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

そのため、それほど改善はあまり大きくありませんが、テールコールの最適化が本当に素晴らしい別のケースがあります。

お互いを呼び出す関数(さらに2つ以上)を持っていて、スタックを保持する必要がない場合(テール再帰的です)、JVMはそれらを最適化できます。あなたが言うことができないので、これは今は不可能です recur 他の機能にジャンプします。これが例です。

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

大量にこれを試してみると、スタックを吹き飛ばすことがわかりますが、テールコールの最適化ではそうしません。

私は少し追加されています。呼ばれる関数があります trampoline これにより、説明する代わりに、これを既に行うことができます(プログラミングスタイルといくつかのオーバーヘッドが変更されています) trampoline まさにそれを行うブログを紹介します。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top