2011-05-11 18 views
5
long b = GC.GetTotalMemory(true); 
SortedDictionary<int, int> sd = new SortedDictionary<int, int>(); 
for (int i = 0; i < 10000; i++) 
{ 
    sd.Add(i, i+1); 
} 
long a = GC.GetTotalMemory(true); 
Console.WriteLine((a - b));    
int reference = sd[10];  

輸出(32位):爲什麼sortedDictionary需要這麼多開銷?

280108 

輸出(64位):

480248 

單獨(在陣列)存放整數需要大約80000

+0

歡迎來到.NET運行時。 – 2011-05-11 08:33:57

+0

,因爲它是一棵樹。還有SortedList和一個普通的列表,它們恰好被排序(確保將項目插入到適當的位置) – harold 2011-09-28 09:27:39

回答

5

內部SortedDictionary<TKey, TValue>使用TreeSet<KeyValuePair<TKey, TValue>>。樹使用Node<T>,顯然它使用節點之間的引用,所以除了每個鍵和值之外,還將引用左右節點以及一些其他屬性。 Node<T>是一個類,因此每個實例都有一個引用類型的傳統開銷。此外,每個節點還存儲一個名爲IsRed的布爾值。

根據WinDbg/SOS,48個字節中的64位單節點的大小,因此它們中的10000個將佔用至少480000個字節。

0:000> !do 0000000002a51d90 
Name:   System.Collections.Generic.SortedSet`1+Node[[System.Collections.Generic.KeyValuePair`2[[System.Int32, mscorlib],[System.Int32, mscorlib]], mscorlib]] 
MethodTable: 000007ff000282c8 
EEClass:  000007ff00133b18 
Size:  48(0x30) bytes  <== Size of a single node 
File:   C:\windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll 
Fields: 
       MT Field Offset     Type VT  Attr   Value  Name 
000007feeddfd6e8 4000624  18  System.Boolean 1 instance    0  IsRed 
000007feee7fd3b8 4000625  20 ...Int32, mscorlib]] 1 instance 0000000002a51db0 Item 
000007ff000282c8 4000626  8 ...lib]], mscorlib]] 0 instance 0000000002a39d90 Left 
000007ff000282c8 4000627  10 ...lib]], mscorlib]] 0 instance 0000000002a69d90 Right 
+0

它是否真的需要這個開銷來支持它的功能? – willem 2011-05-11 09:49:19

+1

@Willem:我想真正的問題是;你需要SortedDictionary的所有功能嗎?如果沒有,那麼佔用較少空間的選項。請參閱文檔的「備註」部分以獲取SortedDictionary的特性列表http://msdn.microsoft.com/en-us/library/f7fta44c.aspx – 2011-05-11 11:04:26

2

它完全取決於SortedDictionary類的實現,與.NET運行時或CLR無關。您可以實現自己的已排序字典並控制分配的內容和數量。可能SortedDictionary實現在內存分配方面效率不高。