2009-10-02 41 views
4

所以我只是從microsoft測試CLR Profiler,我做了一個小程序,它創建了一個帶有1,000,000個雙打的List。我檢查了堆,結果列表<>大小約爲124KB(我不記得確切,但它是在那附近)。這確實震撼了我的世界,如果它有一百萬張雙打的話,它怎麼會是124KB呢?無論如何,之後我決定檢查雙[1000000]。令我驚訝的是(這不是真的,因爲這是我期望的列表<> = P),數組大小爲7.6MB。巨大的差異!C#列表<double>大小vs雙[]大小

他們怎麼不一樣?列表<>如何管理它的內容效率如此(難以置信)?我的意思是,它不像其他7.5 MB是其他地方,因爲在我創建了100萬雙打之後,應用程序的大小大約是3或4 KB。

+1

你的意思是「應用程序的大小約爲3或4 KB」。數組是動態分配的,所以結果exe文件無關緊要。而是看看任務管理器「內存使用」參數 – Dewfy

回答

17

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>是8000036個字節,和底層陣列是8000012個字節。這很適合參考類型(Array)通常的12字節開銷和雙倍1,000,000次8字節的開銷。最重要的是,List<T>爲上面顯示的字段添加了另外24個字節的開銷。

結論:我沒有看到任何證據表明List<double>將佔用較少的空間比double[]爲相同數量的元素。

+0

這是正確的,我三重檢查和大小几乎相同,實際上List <>略大。我不知道第一次會出現什麼問題,但是我在使用CLR分析器運行應用程序時遇到了一些麻煩,所以當我運行1,000,000雙打代碼時,也許我正在查看不同的應用程序實例。謝謝你的理解。 – Carlo

+0

Carlo,我已經學會了質疑分析/分析工具的所有結果,並始終得到「第二意見」,即使結果與我的預期相符。通常情況下,這只是無法解釋,但有時在「奇怪」背後隱藏着更深層次的理解。 – peterchen

1

請注意列表是動態增長的,每次遇到內部緩衝區大小時通常會將大小加倍。因此,新列表最初有4個元素的數組,並且在添加前4個元素之後,第5個元素會導致內部重新分配將緩衝區加倍到(4 * 2)