私は、遅延作業とキャッシュがどのように機能しているかを非常に理解しています。lazy-seqの段階的な例
私は、作業中のlazy-seqのステップバイステップの例が本当に役立つと思います。たとえば、私は、次の質問を読んだ:
をそれはまだ明確ではありません。
私の質問は、別のコールがキャッシュされたコールと "等しい"かどうか、コールがどのように判断し、キャッシュにどれくらい滞在するかということです。私は(source lazy-seq)にしようとしましたが、明らかにJavaの土地にありますので、私はここで運が尽きます。
単純なlazy-seqでは、1つの引数(2の累乗のリストなど)を取ると、5と8を呼び出すとどうなりますか?これらの2つの値だけがキャッシュされていますか?
そして、私が既に遅延関数と呼んでいたすべての入力をキャッシュすることによってメモリを破壊しようとすると、無限のリストを作成してキャッシュするのは何ですか?
これは、それ以降のすべての呼び出しで結果がキャッシュされていると言われているからです。キャッシュされている '1' の引数になる2:
1引数であるために発生 '2' を3にキャッシュされた:引数がされてキャッシュされた3 '' の結果... 2 30:I が2にカウントアップ 30これは私が怠け者だから大丈夫ですが、今は メモリに2 ** 30のキャッシュがあり、これまでのすべての呼び出しをすべてキャッシュします。 以降の呼び出し。
またはキャッシュされた最後の呼び出しですか?
ツリーを引数としてレイジー関数を書くとどうなりますか?それはと同じですか?新しい評価が必要かどうかを知るために、引数のが渡されますか?
この動作は、実行時に何らかの形でトレースできますか?
+1、どうもありがとう... "intertwinned" の場合に起こる遅延関数を呼ん(たとえば、「nth a 50」、「nth a 100」、「nth a 80」、「nt h 150 ")?そして、そのスレッドへの呼び出しはどうなりますか?各スレッドはサイズ1のキャッシュを持っていますか? –
@CedricMartin Lazy seqsは他のすべてのClojureデータ構造と同様に不変であり、スレッドセーフなので、一度計算されると、格納された値はすべてのスレッド間で共有されます。それはリンクされたリストへのポインタ(それはまさにそれが何であるか)として怠惰なseqを考えるのを助けるかもしれません、リストの末尾だけ誰かがそれを求めるまで、次のポインタの計算を気にしません。 – Alex
'キャッシュ'は文字通りリストのセルにあります。特定のスレッドには関連付けられていません。 –