2

大きなデータセットを処理するWeakRefを使用することのオーバーヘッドは何ですか?

私が実行したいタスクは次のようなものです。

huge = get_array_of_weak_refs # 100000000 entries or more :)
result = huge.length * huge.inject(0) { |accum, it| accum += it.total } # much more complicated, just a sample

get_array_of_weak_refsそれは時間がかからず、O(1)複雑であると仮定します。そのため、唯一の懸念はhuge配列のメモリサイズです。

の計算にかかる時間についても、現時点では気にしませんresult

が通常の配列である場合huge、もちろんメモリに収まらない可能性があります。

しかし、WeakRef がその配列の要素として使用される場合、それは役に立ちますか? そのため、要素を反復処理した後、xガベージ コレクションを実行してメモリを解放できます。

このシナリオのオーバーヘッドはどれくらいですか? 代替案はありますか?

4

2 に答える 2

3

WeakRef のコストは非常に高くなる可能性があります。WeakRef は Delegator クラスを拡張し、1.8 実装では Delegator オブジェクトは非常に重いです。Delegator をインスタンス化するたびに、ラップされたオブジェクトのすべてのメソッドが再定義されます。Delegator で文字列をラップすると、最大 2800 個のオブジェクトが割り当てられ、最大 90K のメモリが使用されます。これにより、WeakRef の作成が非常に遅くなり、指しているオブジェクトよりも多くのメモリを使用する可能性があるため、多くの場合、WeakRef は使用できなくなります。

Delegator は 1.9 の Ruby コードで修正されましたが、WeakRef が間違ったオブジェクトを指してしまうというバグがあり、その使用は安全ではありません。

弱い参照を使用する場合は、ref gem (https://rubygems.org/gems/ref) を使用できます。この gem は、参照ごとにオーバーヘッドを 1K 未満のメモリに減らします。Jruby または Rubinius を使用すると、実装はさらに効率的になります。

于 2011-01-11T16:59:15.923 に答える
1

なぜここで弱い参照を使用するのですか? それらは役に立たず、そのようなシナリオ用に設計されていません。

each代わりに、データをチャンクでロードする反復子 ( に応答するオブジェクト) を設定します。

于 2010-11-09T19:56:30.780 に答える