當前位置:成語大全網 - 新華字典 - Dictionary<T1,T2>和List<T>哪個效率更好

Dictionary<T1,T2>和List<T>哪個效率更好

1. 把基本概念

List<T>就是壹個集合,它可以存儲某種類型的列表

Dictionary<T1,T2>,我們俗稱其為字典,他包含壹個Key和與之對應的Value,其目的是能夠根據Key迅速地找到Value,算法復雜度為O(1)。

2. Dictionary<T1,T2>和Hashtable的異同

首先很多人都認同壹個觀點,說Dictionary<T1,T2>是HashTable的泛型版本,這壹點在大致上是正確的,可是當我們運行這樣壹段代碼時,便可看出他們的不同:

1 Dictionary<int, int> dic = new Dictionary<int, int>();

2 dic.Add(1, 5);

3 dic.Add(10, 3);

4 dic.Add(2, 5);

5 foreach (int key in dic.Keys)

6 {

7 Console.WriteLine(key);

8 }

9

10 Hashtable hashtable = new Hashtable();

11 hashtable.Add(1, 5);

12 hashtable.Add(10, 3);

13 hashtable.Add(2, 5);

14 foreach (object key in hashtable.Keys)

15 {

16 Console.WriteLine(key.ToString());

17 }

Dictionary<T1,T2>是根據插入的順序來遍歷,但是Hashtable在插入時會打亂其位置。

並且我們在用Reflector看源碼的時候也會發現Hashtable是線程安全的,而Dictionary明顯不具備如此特性。

3. Dictionary<T1,T2>的存儲原理

說到字典,我們就不能不說其存儲結構,他會根據Key通過Hash計算來得到其應存放的虛擬內存地址,這也是在哈希表中Key必須唯壹的原因,當我們按照Key進行查找時,首先就是根據Key計算出其所存放的虛擬內存地址,去對應的內存地址找數據,得到其Value。

這壹點HashTable與其相同。

4. 問題提出

我們為了討論遍歷時Dictionary和List的效率,有個高人寫了個代碼,這是載圖

很明顯,LIST效率要好的多。

5. 問題剖析

同樣是集合,為什麽性能會有這樣的差距。我們要從存儲結構和操作系統的原理談起。

首先我們清楚List<T>是對數組做了壹層包裝,我們在數據結構上稱之為線性表,而線性表的概念是,在內存中的連續區域,除了首節點和尾節點外,每個節點都有著其唯壹的前驅結點和後續節點。我們在這裏關註的是連續這個概念。

而HashTable或者Dictionary,他是根據Key而根據Hash算法分析產生的內存地址,因此在宏觀上是不連續的,雖然微軟對其算法也進行了很大的優化。

由於這樣的不連續,在遍歷時,Dictionary必然會產生大量的內存換頁操作,而List只需要進行最少的內存換頁即可,這就是List和Dictionary在遍歷時效率差異的根本原因。

6. 再談Dictionary

也許很多人說,既然Dictionary如此強大,那麽我們為什麽不用Dictionary來代替壹切集合呢?

在這裏我們除了剛才的遍歷問題,還要提到Dictionary的存儲空間問題,在Dictionary中,除了要存儲我們實際需要的Value外,還需要壹個輔助變量Key,這就造成了內存空間的雙重浪費。

而且在尾部插入時,List只需要在其原有的地址基礎上向後延續存儲即可,而Dictionary卻需要經過復雜的Hash計算,這也是性能損耗的地方。