47

純粋関数型言語では、データは不変です。参照カウントでは、参照サイクルを作成するには、作成済みのデータを変更する必要があります。純粋に関数型の言語は、サイクルの可能性を気にせずに参照カウントを使用できるようです。そうですね?もしそうなら、なぜ彼らはしないのですか?

多くの場合、参照カウントは GC よりも遅いことは理解していますが、少なくとも一時停止時間は短縮されます。一時停止時間が悪い場合に参照カウントを使用するオプションがあると便利です。

4

6 に答える 6

30

Java や C# などの他のマネージ言語と比較して、純粋関数型言語は狂ったように割り当てます。また、異なるサイズのオブジェクトを割り当てます。既知の最速の割り当て戦略は、連続する空き領域 (「ナーサリ」とも呼ばれます) から割り当て、次に使用可能な空き領域を指すようにハードウェア レジスタを予約することです。ヒープからの割り当ては、スタックからの割り当てと同じくらい高速になります。

参照カウントは、この割り当て戦略と基本的に互換性がありません。参照カウントは、オブジェクトを空きリストに入れ、再び削除します。参照カウントには、新しいオブジェクトが作成されるときに参照カウントを更新するために必要なかなりのオーバーヘッドもあります (上記のように、純粋な関数型言語は狂ったように動作します)。

参照カウントは、次のような状況で非常にうまく機能する傾向があります。

  • ほとんどすべてのヒープ メモリは、ライブ オブジェクトを保持するために使用されます。
  • 割り当てとポインターの割り当ては、他の操作に比べてまれです。
  • 参照は、別のプロセッサまたはコンピュータで管理できます。

今日の最高の高性能参照カウント システムがどのように機能するかを理解するには、David BaconErez Petrankの研究を調べてください。

于 2009-04-27T02:08:01.570 に答える
9

そうですね?

そうではありません。相互に再帰的な値を同時に定義するだけで、純粋な関数型プログラミングを使用して循環データ構造を作成できます。たとえば、OCaml では次のようになります。

let rec xs = 0::ys and ys = 1::xs

ただし、意図的に循環構造を作成できない言語を定義することは可能です。結果は単方向ヒープと呼ばれ、その主な利点は、ガベージ コレクションが参照カウントと同じくらい簡単になることです。

もしそうなら、なぜ彼らはしないのですか?

一部の言語では循環が禁止され、参照カウントが使用されます。Erlang と Mathematica がその例です。

たとえば、Mathematica で値を参照すると、その値のディープ コピーが作成されるため、元の値を変更してもコピーは変更されません。

In[1] := xs = {1, 2, 3}
Out[1] = {1, 2, 3}

In[2] := ys = xs
Out[2] = {1, 2, 3}

In[3] := xs[[1]] = 5
Out[3] = 5

In[4] := xs
Out[4] = {5, 2, 3}

In[5] := ys
Out[5] = {1, 2, 3}
于 2010-12-22T21:49:06.470 に答える
8

Lisp Machineの発明者であるDavid Moonについて語ったこの寓話について考えてみましょう。

ある日、ある学生が Moon に来て、こう言いました。

ムーンは辛抱強く生徒に次の話をしました。

「ある日、学生がムーンに来て言った:「私はより良いガベージコレクターを作る方法を理解しています...

于 2009-05-25T04:23:59.780 に答える