49

.Net の特定のコレクション タイプには、オプションの「初期容量」コンストラクタ パラメータがあります。例えば:

Dictionary<string, string> something = new Dictionary<string,string>(20);

List<string> anything = new List<string>(50);

MSDN で、これらのオブジェクトのデフォルトの初期容量を見つけることができないようです。

辞書に 12 項目しか格納しないことがわかっている場合、初期容量を 20 などに設定するのは理にかなっていませんか?

私の推論は、容量が StringBuilder の場合と同じように増加し、容量がヒットするたびに 2 倍になり、それぞれの再割り当てにコストがかかると仮定すると、データを保持することがわかっているサイズに事前にサイズを設定しておかない理由です。念のため部屋?初期容量が 100 で、必要なメモリが 10 個程度しかないことがわかっている場合、残りのメモリは無駄に割り当てられているように見えます。

4

4 に答える 4

82

デフォルト値が文書化されていない場合、その理由は、最適な初期容量が実装の詳細であり、フレームワークのバージョン間で変更される可能性があるためです。つまり、特定の既定値を想定するコードを記述しないでください。

容量を指定したコンストラクターのオーバーロードは、予想されるアイテムの数がクラスよりもよくわかっている場合に使用します。たとえば、50 個の値のコレクションを作成し、この数が増加しないことがわかっている場合は、50 の容量でコレクションを初期化できるため、既定の容量がそれよりも小さい場合にサイズを変更する必要はありません。

つまり、Reflector を使用してデフォルト値を決定できます。たとえば、.NET 4.0 (およびおそらく以前のバージョンも) では、

  • List<T> は、容量 0 で初期化されます。最初の項目が追加されると、容量 4 に再初期化されます。その後、容量に達するたびに容量が 2 倍になります。

  • Dictionary<T> も容量 0 で初期化されます。ただし、容量を増やすためにまったく異なるアルゴリズムを使用します。常に容量を素数まで増やします。

于 2010-05-03T20:21:36.743 に答える
12

サイズがわかっている場合は、それを教えてください。ほとんどの「小さな」ケースではマイナーな最適化ですが、より大きなコレクションには役立ちます。「まともな」量のデータを投入している場合、複数の配列を割り当て、コピー、および収集する必要がなくなるため、主にこれについて心配します。

実際、ほとんどのコレクションは倍加戦略を使用しています。

于 2010-05-03T20:22:14.963 に答える
9

ソースを確認すると、両方のデフォルトの容量List<T>Dictionary<TKey, TValue>0 です。

于 2010-05-03T20:22:01.233 に答える