2011-12-11 7 views

答えて

10

実際には同じ量のメモリ(技術的には、より多くのデータを簡単に増やすことができるように過剰割り当てされているため、これ以上のメモリが消費されます)。

.NETの一般的なコレクションでは、保持するアイテムをボックスに入れる必要はありません。これは、大量のメモリとパフォーマンスのシンクになります。

+3

実装については、List <>は配列ですか? –

+2

@Daniel:はい、拡張可能な配列です。 – sepp2k

+1

@DanielMošmondor:[はい](http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx)* List(Of T)クラスは、ArrayListクラスの汎用的な同等です。 * – Jon

1

私の知る限り、.NETはテンプレート(ジェネリック)特化していないことをご了承ください。

.Netには、(プログラマとして)型引数に応じて異なるコードを提供できるという意味でのテンプレート特殊化はありません。しかし、コンパイラは参照型とは異なる値の型に対して異なるコードを生成することができます(Javaではそうではありません)。値の型はジェネリックコンテナに入れられたときに囲まれません。それらは効率的に保存されます。

5

List<T>は、配列T[]を所有しています。この配列には指数関数的な成長戦略が使用されているため、n要素のリストには、通常、nより大きいサイズのバッキング配列があります。また、小さな配列はガーベジコレクションされる必要があります。これは、LoH上にある十分な大きさであれば迷惑になる可能性があります。

しかし、これは、たとえばコンストラクタパラメータなどの容量を手動で指定することで回避できます。次に、希望の容量を持つ1つのアレイが割り当てられますので、上記の両方の問題を回避できます。

さらに、List<T>には、リストオブジェクト自体のO(1)オーバーヘッドがありません。


ただし、ジェネリックスを使用する場合、要素あたりのオーバーヘッドはありません。ランタイムは、渡す値の種類ごとに特殊なバージョンを作成します。要素のボクシングは発生しません。

しかし、特定の型パラメータの実装を効果的にオーバーロードするC++スタイルテンプレートの特殊化は使用できません。すべての汎用インスタンシエーションは、同じC#コードを共有します。

つまり、特殊なILコードはありませんが、各値タイプは、同じソースコードに基づいて特殊なマシンコード実装を取得します。

1

リストの使用は、プレーンな配列を使用するよりも実用的です。パフォーマンスとメモリ消費のキーは、リストの容量です。デフォルトでは、値4で始まり、リストの要素が定義された容量に達するたびに8,16,32,64、...に増加します。各インクリメントは内部再割り当てとArray.Copyに変換されます。したがって、1000アイテムのリストがあり、1日に100アイテムが予想される場合は、容量1200(予測100%の誤差マージン)のリストをインスタンス化できます。このようにして、10001項目を追加するたびに2000項目の再割り当てを回避し、継続的な再割り当てとArray.Copyを使用して既存の1000項目を埋め込むことができます。

関連する問題

 関連する問題