C#中哈希表與List的比較


簡單概念

在c#中,List是順序線性表(非鏈表),用一組地址連續的存儲單元依次存儲數據元素的線性結構。

哈希表也叫散列表,是一種通過把關鍵碼值映射到表中一個位置來訪問記錄的數據結構。c#中的哈希表有Hashtable,Dictionary,Hashtable繼承自Map,實現一個key-value映射的關系。Dictionary則是一種泛型哈希表,不同於Hashtable的key無序,Dictionary是按照順序存儲的。哈希表的特點是:1.查找速度快,2.不能有重復的key。

創建過程

在c#中,我們實例化list時,如果不指定容量,則內部會生成一個靜態的空數組,有添加操作時,實例化為一個長度為4的數組,滿了以后,自動擴充為兩倍的容量。

哈希表也是類似的情況,先默認生成一個長度為11的哈希表,滿后,自動添加,而添加規則是內部循環素數數組,稍大於當前的長度,比如15 ,則長度設定為17。在哈希表創建可分為確定哈希函數,解決哈希沖突兩個步驟。

實驗執行結果

下面進行兩個實驗,實驗一,比較Hashtable,Dictionary,List三者在不同長度時的創建速度,實驗二比較三者在不同時間時的查找速度。(實驗代碼在最后)

硬件:intel core 2 quad cpu @ 2.66GHZ,4GB內存。

軟件:windows 2008,2010 VS編譯環境。

表1.三者的創建時間

長度\類型

Hashtable

Dictionary

List

1

0.001s

0s

0s

10

0S

0S

0s

100

0S

0S

0s

1000

0.003s

0.005s

0.001s

10000

0.0032s

0.003s

0.002s

100000

0.038s

0.042s

0.002s

1000000

0.520s

0.512s

0.015s

3000000

1.807s

1.441s

0.042s

6000000

3.752s

2.952s

0.087s

8000000

4.744s

3.740s

0.102s

 

 

 

表2.三者的查找時間

長度\類型

Hashtable

Dictionary

List

1

0s

0s

0s

10

0s

0s

0s

100

0s

0s

0s

1000

0s

0s

0s

10000

0s

0s

0.001s

100000

0s

0s

0.010s

1000000

0s

0s

0.009s

3000000

0s

0s

0.009s

6000000

0s

0s

0.058s

8000000

0s

0s

0.077s

總結

實驗一表明:哈希表比list需要花費更多的時間建立數據結構,這是因為哈希表花費時間去解決哈希沖突,而list不需要。但需要注意的是建立操作只需要執行一次。

 

實驗二表明:哈希表的查找速度幾乎不需要花費時間,這是因為哈希表在添加一對元素(key-value)時,就已經記錄下value的位置,所以查找時就會非常的快。哈希的查找復雜度O(1),list 的查找復雜度是O(n)。

 

哈希表的高速查找是空間換時間的典型應用,前期的建立時間隨着數量級的增加而增加,后期的查找則永遠是O(1)。所以我們得出結論:如果面對海量數據,且需要大量搜索,那建議使用哈希表。而當面對小量數據(數量級由服務器決定)時,使用List更合適。

 

最后友情提醒:第一,雖然在查找上哈希占有優勢,但不足的是1.占有空間大,2.不能有重復健。第二,如果需要使用哈希表,建議多使用Dictionary。Dictionary的運行時間比hashtable稍快,而且Dictionary是類型安全的,這有助於我們寫出更健壯更具可讀性的代碼,省去我們強制轉化的麻煩。Dictionary是泛型的,當K或V是值類型時,其速度遠遠超過Hashtable。

 

[csharp] view plain copy print ?
  1. /* 
  2.  *Author: chao 
  3.  *Date:2012.3.27 
  4.  *Fun: Compare list with hash in c# 
  5.  */  
  6. using System;  
  7. using System.Collections.Generic;  
  8. using System.Linq;  
  9. using System.Text;  
  10. using System.Collections;  
  11. namespace hash_vs_list  
  12. {  
  13.     class Program  
  14.     {  
  15.   
  16.         const int MAX = 50000;  
  17.         static void Main(string[] args)  
  18.         {  
  19.             //hash_table   
  20.             Console.WriteLine("hash_table");  
  21.             TimeSpan hash_start = new TimeSpan(DateTime.Now.Ticks);  //開始時間   
  22.             Hashtable h1 = new Hashtable();  
  23.             for (int i = 0; i < MAX; i++)  
  24.                 h1.Add(i, i.ToString());  
  25.             TimeSpan hash_end = new TimeSpan(DateTime.Now.Ticks);  //結束時間   
  26.             TimeSpan hash_diff = hash_start.Subtract(hash_end).Duration();//  計算時間差   
  27.             string hash_create_diff = hash_diff.TotalSeconds.ToString();   //     
  28.   
  29.             //hashtable search   
  30.             hash_start = new TimeSpan(DateTime.Now.Ticks);  
  31.             string tmp = h1[0].ToString();  
  32.             hash_end = new TimeSpan(DateTime.Now.Ticks);  
  33.             hash_diff = hash_start.Subtract(hash_end).Duration();  
  34.             string hash_search_diff = hash_diff.TotalSeconds.ToString();  
  35.   
  36.             Console.WriteLine("create:{0} search:{1}", hash_create_diff, hash_search_diff);  
  37.             Console.WriteLine();  
  38.   
  39.   
  40.   
  41.   
  42.             //dict   
  43.             Console.WriteLine("dictionary");  
  44.             Dictionary<intstring> dict = new Dictionary<intstring>();  
  45.             TimeSpan dict_start = new TimeSpan(DateTime.Now.Ticks);  
  46.             for (int i = 0; i < MAX; i++)  
  47.             {  
  48.                 dict.Add(i, i.ToString());  
  49.             }  
  50.             TimeSpan dict_end = new TimeSpan(DateTime.Now.Ticks);  
  51.             TimeSpan dict_diff = dict_start.Subtract(dict_end).Duration();  
  52.             string dict_create_diff = dict_diff.TotalSeconds.ToString();  
  53.               
  54.             //dict search   
  55.             dict_start = new TimeSpan(DateTime.Now.Ticks);  
  56.             tmp = dict[0];  
  57.             dict_end = new TimeSpan(DateTime.Now.Ticks);  
  58.             dict_diff = dict_start.Subtract(dict_end).Duration();  
  59.             string dict_search_diff = dict_diff.TotalSeconds.ToString();  
  60.             Console.WriteLine("create:{0} search:{1}", dict_create_diff, dict_search_diff);  
  61.             Console.WriteLine();  
  62.   
  63.   
  64.   
  65.             //list create   
  66.             Console.WriteLine("list");  
  67.             TimeSpan list_start = new TimeSpan(DateTime.Now.Ticks);  
  68.             List<int> l1 = new List<int>();  
  69.             for (int i = 0; i < MAX; i++)  
  70.                 l1.Add(i);  
  71.             TimeSpan list_end = new TimeSpan(DateTime.Now.Ticks);  
  72.             TimeSpan list_diff = list_start.Subtract(list_end).Duration();  
  73.             string list_create_diff = list_diff.TotalSeconds.ToString();  
  74.   
  75.   
  76.             //list foreach   
  77.             list_start = new TimeSpan(DateTime.Now.Ticks);  
  78.             foreach (int i in l1)  
  79.             {  
  80.                 if (i == MAX)  
  81.                     break;  
  82.             }  
  83.             list_end = new TimeSpan(DateTime.Now.Ticks);  
  84.             list_diff = list_start.Subtract(list_end).Duration();  
  85.             string list_foreach_diff = list_diff.TotalSeconds.ToString();  
  86.             Console.WriteLine("create:{0},foreach:{1}", list_create_diff, list_foreach_diff);  
  87.             Console.WriteLine();  
  88.   
  89.   
  90.             Console.Read();  
  91.         }  
  92.     }  
  93. }  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM