基於昨天在群里討論的慘敗,今早特地睡不着就早早爬起來,鑽研前人對集合的理解,這文很多都是抄的,就當記憶記憶。
首先這四個大致可以分為兩類,第一類是list和array,第二類是dictionary和hashtable。
1.list和array
在《Effective C#》中有這樣一條規則,就是說:在初始化List之前最好對List初始化大小。
在初始化List時,List會新建一個數組,然后把數組的長度設置為原來的二倍(如果原有的數組長度為0,那就默認將數組的長度設置為4)。
List<T>是對Array的進一步封裝,說得再直接點,我願意理解List<T>為Array的可擴充版本,然后擴展了一些方法;
List是基於Array存在的,因此,在創建一個List對象時,需要耗費比Array相對更多的時間,以及更大的空間,因為List除了初始化內部的items外還需要初始化一些其他的屬性。而且在方法調用時,這點我沒有證實,只是一個猜測,List需要的是再去調用Array的相關方法,因此也許會存在方法調用的時間消耗問題。
總結:如果初始化時確定大小,那么就使用Array。如果初始化時不確定大小,那么就使用List。當然,其實完全可以自己去實現List中的數組擴充功能的,也許會更棒,因為我們沒有必要去將Array每次都擴充為原來的二倍。
Array相對於List還有個優勢就是:多維數組比List的嵌套更容易理解,也就是說int[][](或者是int[,])要強於List<list>,也就說在類型確定且多維的情況下,用Array要優於List。
2.dictionary和hashtable的區別
首先很多人都認同一個觀點,說Dictionary<T1,T2>是HashTable的泛型版本,這一點在大致上是正確的。
Hashtable是線程安全的,而Dictionary明顯不具備如此特性。
說到字典,我們就不能不說其存儲結構,他會根據Key通過Hash計算來得到其應存放的虛擬內存地址,這也是在哈希表中Key必須唯一的原因,當我們按照Key進行查找時,首先就是根據Key計算出其所存放的虛擬內存地址,去對應的內存地址找數據,得到其Value。這一點HashTable與其相同。
3.第一類是list和array,第二類是dictionary和hashtable對比
同樣是集合,為什么性能會有這樣的差距。我們要從存儲結構和操作系統的原理談起。
首先我們清楚List<T>是對數組做了一層包裝,我們在數據結構上稱之為線性表,而線性表的概念是,在內存中的連續區域,除了首節點和尾節點外,每個節點都有着其唯一的前驅結點和后續節點。我們在這里關注的是連續這個概念。
而HashTable或者Dictionary,他是根據Key而根據Hash算法分析產生的內存地址,因此在宏觀上是不連續的,雖然微軟對其算法也進行了很大的優化。
由於這樣的不連續,在遍歷時,Dictionary必然會產生大量的內存換頁操作,而List只需要進行最少的內存換頁即可,這就是List和Dictionary在遍歷時效率差異的根本原因。
Dictionary的存儲空間問題,在Dictionary中,除了要存儲我們實際需要的Value外,還需要一個輔助變量Key,這就造成了內存空間的雙重浪費。
而且在尾部插入時,List只需要在其原有的地址基礎上向后延續存儲即可,而Dictionary卻需要經過復雜的Hash計算,這也是性能損耗的地方。
內容取自:http://blog.csdn.net/teresa502/article/details/8266878和http://www.cnblogs.com/kym/archive/2009/03/09/1406657.html 感謝大神們的教誨我大致了解了。
然后是第一次亂抄,看的不順直接看原文吧。