4

Often I produce a collection on demand to save on instance data size. The consumer iterates through the collection probably only once, before its garbage collected. The consumer doesn't care about the order of the collection doesn't need to sort on it certainly doesn't need to mutate it, or any of its elements. What's the most efficient type safe collection in Scala? - an Array?

Later edit: It occurs to me that there are probably quite a few situations when I could use Sets. Is it good to use Sets when possible or just to use them when set functionality is really needed?

4

2 に答える 2

9

はい、すべてのコレクション データ構造の中で、配列のサイズが事前にわかっている場合、配列のオーバーヘッドは最小になります。

事前にサイズがわからない場合でも、ArrayBuffer*を選択します。スペースが不足したときに基になる配列を拡張するために使用されるアルゴリズムは、非常に効率的です。

(リンクされた) ListまたはStreamを使用しない*でください。これらのクラスには要素ごとに 1 つのヒープ割り当てが含まれるためです。最新の JVM ガベージ コレクタは優れていますが、無料では機能しません。

*: ただし、いくつかのマイクロベンチマークへのリンクについては、質問に対する@user unknownのコメントを参照してください。現在のArrayBuffer実装は最適ではない可能性があります。

もご覧ください.view。多くの場合、実際に中間結果を保存する必要はありません。代わりに、 などを使用.map.filterて、コレクションの「説明」を作成できます。O(1)操作 (マップ、フィルターなど) は、多くの場合空間でコレクションを反復処理する場合にのみ実行されます。欠点は、これらのビューがクエリされるたびに再計算されることです。(ただし、単純なフィルターと巨大な基礎となるコレクションを使用すると、これはより効率的である可能性があります)

また、可変データ構造のビューには特に注意してください。ビューは、基になるデータ構造の状態をキャプチャしません。変わると景色も変わる。ただし、不変データ構造のビューは非常にうまく機能します。最後に、ビューには明らかに基礎となるデータ構造への参照が含まれています。つまり、プログラムがビューを保持している間、ガベージ コレクションは行われません。

(更新) ベクターは、特に大規模なシーケンスの場合、ストレージ効率と柔軟性のバランスが取れているようです。

于 2012-05-11T00:47:55.323 に答える
3

要素を保存する必要がありますか? それらをオンデマンドで計算できませんか? 値を保存する代わりにオンデマンドで計算できる場合は、メモリをほとんど消費せずにジョブを実行するTraversableまたはを作成できます (クラス自体を除いて、 にIterableメモリは消費されません)。Traversable

于 2012-05-11T21:52:54.440 に答える