.Net 中HashTable,HashMap 和 Dictionary 和List和DataTable的比較

參考資料html

http://www.cnblogs.com/MichaelYin/archive/2011/02/14/1954724.htmljava

http://zhidao.baidu.com/link?url=DonFgOvFddsAVKUjY4WBwCgE6cO4jLjapPS14Hb3iobC3f6QwYB-3R6OQkRArowg2vzxLnTiujkHss6iy2wFDq面試

http://www.cnblogs.com/lori/archive/2011/08/09/2132380.html算法

http://www.coding123.net/article/20120419/DataTable-IList-compare.aspx數組

 

 

首先:安全

(ling)在.Net  模仿java 的過程當中   拋棄了 HashMap ,因此之後再去面試.Net的時候當別人問你HashTable 和HashMap 的區別的時候,請告訴他,C#.Net 中  沒有HashMap 數據結構

好接下來進入正題多線程

.Net 中HashTable 和 Dictionary<key,value> 和List<T>的比較(不要問我怎麼和題目不同),本文只比較兩種數據類型在使用時 功能相近的狀況,差異太大的 則不比較。函數

先來比較性能

(yi)HashTable    和Dic 

 

數據結構

Hashtable和Dictionary從數據結構上來講都屬於Hashtable(哈希表),都是對關鍵字(鍵值)進行散列操做,將關鍵字散列到Hashtable的某一個槽位中去,不一樣的是處理碰撞的方法。散列函數有可能將不一樣的關鍵字散列到Hashtable中的同一個槽中去,這個時候咱們稱發生了碰撞,爲了將數據插入進去,咱們須要另外的方法來解決這個問題。

採用鏈表法的是Dic    而採用開放尋址法(open addressing)-中  雙重散列的方法的是 HashTable

至於這兩種數據結構的使用方法  請自行閱讀算法導論   或者參照網上博客

但從底層的數據結構能夠發現

若是增刪的動做不少的話 推薦使用Dic  由於解決碰撞的方式  是List.Add

若是改動的動做不多  查詢的動做不少的話   則推薦 使用HashTable  由於映射查找以後  只須要跳躍查找到  碰撞後移動數據便可,另外當增長數據太多時,開放尋址的擴容很耗費性能(請閱讀<算法導論>)

Dic 和HashTable使用比較

1:單線程程序中推薦使用 Dictionary, 有泛型優點, 且讀取速度較快, 容量利用更充分.
 2:多線程程序中推薦使用 Hashtable, 默認的 Hashtable 容許單線程寫入, 多線程讀取, 對 Hashtable 進一步調用  Synchronized() 方法能夠得到徹底線程安全的類型. 而 Dictionary 非線程安全, 必須人爲使用 lock 語句進行保護,  效率大減.
 3:Dictionary 有按插入順序排列數據的特性 (注: 但當調用 Remove() 刪除過節點後順序被打亂), 所以在須要體現順序的情境中使用 Dictionary 能得到必定方便. //Dic遍歷時  會採用插入時的遍歷,而hashTable 採用遍歷時 則是打亂的

Hashtable 類和 Dictionary<TKey, TValue> 泛型類實現 IDictionary 接口
Dictionary<TKey, TValue> 泛型類還實現 IDictionary<TKey, TValue>泛型接口。
所以,這些集合中的每一個元素都是一個鍵/值對。

Dictionary<TKey, TValue> 類與 Hashtable 類的功能相同
對於值類型,特定類型(不包括 Object)的 Dictionary<TKey, TValue> 的性能優於 Hashtable,這是由於 Hashtable 的元素屬於 Object  類型,因此在存儲或檢索值類型時一般發生裝箱和取消裝箱操做。

 

(er)Dic  和 List<T>

關於數據結構:

在前邊的比較已經介紹了Dic   那麼 List <T> 的數據結構是什麼樣子的:

List<T>是 ArrayList 的泛型等效類(繼承了泛型接口)

堆中的樣子是這樣的

 

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

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

問題剖析

一樣是集合,爲何性能會有這樣的差距。咱們要從存儲結構和操做系統的原理談起。

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

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

因爲這樣的不連續,在遍歷時,Dictionary必然會產生大量的內存換頁操做,而List只須要進行最少的內存換頁便可,這就是List和Dictionary在遍歷時效率差別的根本緣由。

因此根據value 的查找  dic 的效率是高於 List 的 可是遍歷的話   則Dic 要差點。這就比如你要摘抄書裏邊的全部文字  是根據目錄 查一個找一篇文章 快,仍是直接從正文開始 從頭至尾快遍歷快同樣。單獨的找某一篇知道題目(key)的文章 固然是從目錄快了

再談Dictionary

也許不少人說,既然Dictionary如此強大,那麼咱們爲何不用Dictionary來代替一切集合呢?

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

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

 

List<T>和 DataTable

DataTable,IList性能比較
1)二進制序列化的狀況

從測試結果能夠看出,IList<T>序列化的文件大小比DataTable小得多,這意味着在數據傳輸中帶寬佔用小不少,因此在設計Remoting接口時儘可能使用IList<T>做返回值。

2)XML序列化的狀況

從測試結果能夠看出,IList<T>序列化後的文件比一樣比DataTable小,但差距已經沒有二進制序列化那麼明顯了。並且IList<T>的二進制序列化和XML序列化相差很大,因此remoteing中建議使用二進制序列化。

3)操做性比較

  DataTable有支持數據的提交、回滾、查詢等強大的方法,但訪問單元格內容的時候不方便,還要類型轉換。

  IList<T>則訪問項的屬性比較方便,有屬性自動提示,不用類型轉換,有LINQ的協助也能實現強大的查詢

相關文章
相關標籤/搜索