首先這四個大致可以分為兩類截碴,第一類是 List 和 Array(數(shù)組),第二類是 Dictionary 和 Hashtable
-
List 和 Array(數(shù)組)
在初始化List之前最好對List初始化大小蛉威。在初始化 List 時日丹,List 會新建一個數(shù)組,然后把數(shù)組的長度設置為原來的二倍(如果原有的數(shù)組長度為0蚯嫌,那就默認將數(shù)組的長度設置為4)哲虾。List<T> 是對 Array 的進一步封裝,說得再直接點择示,可以理解 List<T> 為 Array 的可擴充版本束凑,然后擴展了一些方法。
List 是基于 Array 存在的栅盲,因此汪诉,在創(chuàng)建一個 List 對象時,需要耗費比 Array 相對更多的時間谈秫,以及更大的空間扒寄,因為 List 除了初始化內(nèi)部的 items 外還需要初始化一些其他的屬性。而且在方法調(diào)用時拟烫,List需要的是再去調(diào)用Array的相關方法该编,因此也許會存在方法調(diào)用的時間消耗問題。
如果初始化時確定大小硕淑,那么就使用 Array课竣。如果初始化時不確定大小,那么就使用 List置媳。當然于樟,其實完全可以自己去實現(xiàn)List中的數(shù)組擴充功能的,也許會更棒半开,因為我們沒有必要去將Array每次都擴充為原來的二倍隔披。
Array 相對于 List 還有個優(yōu)勢就是:多維數(shù)組比List的嵌套更容易理解赃份,也就是說 int[][](或者是 int[,] )要強于 List<list>寂拆,也就說在類型確定且多維的情況下,用 Array 要優(yōu)于 List抓韩。
-
Dictionary 和 Hashtable
首先很多人都認同一個觀點纠永,說Dictionary<T1,T2>是HashTable的泛型版本,這一點在大致上是正確的谒拴。
Hashtable 是線程安全的尝江,而 Dictionary 明顯不具備如此特性。單線程程序中推薦使用 Dictionary, 有泛型優(yōu)勢, 且讀取速度較快, 容量利用更充分英上。
Dictionary<T1,T2> 是根據(jù)插入的順序來遍歷炭序,但是 Hashtable 在插入時會打亂其位置啤覆。
HashTable 與 Dictionary 的存儲原理是相同的。 都是根據(jù) Key 通過 Hash 計算來得到其應存放的虛擬內(nèi)存地址惭聂,這也是在哈希表中 Key 必須唯一的原因窗声,當我們按照 Key 進行查找時,首先就是根據(jù) Key 計算出其所存放的虛擬內(nèi)存地址辜纲,去對應的內(nèi)存地址找數(shù)據(jù)笨觅,得到其 Value。
-
Dictionary 和 List
List<T> 是對數(shù)組做了一層包裝耕腾,我們在數(shù)據(jù)結構上稱之為線性表见剩,而線性表的概念是,在內(nèi)存中的連續(xù)區(qū)域扫俺,除了首節(jié)點和尾節(jié)點外苍苞,每個節(jié)點都有著其唯一的前驅(qū)結點和后續(xù)節(jié)點。我們在這里關注的是連續(xù)這個概念狼纬。
而 HashTable 或者 Dictionary柒啤,他是根據(jù) Key 而根據(jù) Hash 算法分析產(chǎn)生的內(nèi)存地址,因此在宏觀上是不連續(xù)的畸颅,雖然微軟對其算法也進行了很大的優(yōu)化担巩。
由于這樣的不連續(xù),在遍歷時没炒,Dictionary 必然會產(chǎn)生大量的內(nèi)存換頁操作涛癌,而List只需要進行最少的內(nèi)存換頁即可,這就是 List 和 Dictionary 在遍歷時效率差異的根本原因送火。而且在尾部插入時拳话,List 只需要在其原有的地址基礎上向后延續(xù)存儲即可,而 Dictionary 卻需要經(jīng)過復雜的 Hash
計算种吸,這也是性能損耗的地方弃衍。