5

だから私はちょうどマイクロソフトのCLRプロファイラーをテストしていて、1,000,000のdoubleを含むリストを作成する小さなプログラムを実行しました。ヒープを確認したところ、List <>のサイズは約124KBでした(正確には覚えていませんが、そのあたりでした)。これは本当に私の世界を揺るがしました、もしそれが100万のダブルを持っていたら、どうして124KBになるのでしょうか?とにかく、その後、double[1000000]をチェックすることにしました。そして驚いたことに(これはList <> = Pで期待していたものなので、実際にはそうではありません)、配列サイズは7.6MBです。大きな違い!!

どうして違うの?List <>はどのようにアイテムを管理するので、(信じられないほど)メモリ効率が高くなりますか?つまり、他の7.5 mbが他の場所にあったのとは異なります。これは、100万のdoubleを作成した後、アプリケーションのサイズが約3または4KB大きくなったためです。

4

2 に答える 2

18

List<T>List<T>配列を使用して値/参照を格納するため、オーバーヘッドがほとんど追加されないことを除けば、サイズに違いがあるとは思えません。

以下のコードを考えると

var size = 1000000;
var numbers = new List<double>(size);
for (int i = 0; i < size; i++) {
   numbers.Add(0d);
}

関連するオブジェクトのヒープは次のようになります

0:000> !dumpheap -type Generic.List  
 Address       MT     Size
01eb29a4 662ed948       24     
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
662ed948        1           24 System.Collections.Generic.List`1[[System.Double,  mscorlib]]
Total 1 objects

0:000> !objsize 01eb29a4    <=== Get the size of List<Double>
sizeof(01eb29a4) =      8000036 (    0x7a1224) bytes     (System.Collections.Generic.List`1[[System.Double, mscorlib]])

0:000> !do 01eb29a4 
Name: System.Collections.Generic.List`1[[System.Double, mscorlib]]
MethodTable: 662ed948
EEClass: 65ad84f8
Size: 24(0x18) bytes
 (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
65cd1d28  40009d8        4      System.Double[]  0 instance 02eb3250 _items    <=== The array holding the data
65ccaaf0  40009d9        c         System.Int32  1 instance  1000000 _size
65ccaaf0  40009da       10         System.Int32  1 instance  1000000 _version
65cc84c0  40009db        8        System.Object  0 instance 00000000 _syncRoot
65cd1d28  40009dc        0      System.Double[]  0   shared   static _emptyArray
    >> Domain:Value dynamic statics NYI
 00505438:NotInit  <<

0:000> !objsize 02eb3250 <=== Get the size of the array holding the data
sizeof(02eb3250) =      8000012 (    0x7a120c) bytes (System.Double[])

したがって、List<double>は8,000,036バイトであり、基になる配列は8,000,012バイトです。これは、参照型()の通常の12バイトのオーバーヘッド、Arrayおよび倍精度浮動小数点数の1,000,000x8バイトによく適合します。その上に、List<T>上記のフィールドにさらに24バイトのオーバーヘッドが追加されます。

結論:同じ数の要素List<double>よりも少ないスペースを占めるという証拠は見当たりません。double[]

于 2009-10-02T07:59:31.807 に答える
1

リストは動的に拡大され、通常、内部バッファサイズに達するたびにサイズが2倍になることに注意してください。したがって、新しいリストには最初は4要素の配列のようなものがあり、最初の4つの要素を追加した後、5番目の要素によって内部再割り当てによってバッファが2倍になり(4 * 2)ます。

于 2009-10-02T08:54:37.040 に答える