简单概念

在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。

  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. const int MAX = 50000;
  16. static void Main(string[] args)
  17. {
  18. //hash_table
  19. Console.WriteLine("hash_table");
  20. TimeSpan hash_start = new TimeSpan(DateTime.Now.Ticks);  //开始时间
  21. Hashtable h1 = new Hashtable();
  22. for (int i = 0; i < MAX; i++)
  23. h1.Add(i, i.ToString());
  24. TimeSpan hash_end = new TimeSpan(DateTime.Now.Ticks);  //结束时间
  25. TimeSpan hash_diff = hash_start.Subtract(hash_end).Duration();//  计算时间差
  26. string hash_create_diff = hash_diff.TotalSeconds.ToString();   //
  27. //hashtable search
  28. hash_start = new TimeSpan(DateTime.Now.Ticks);
  29. string tmp = h1[0].ToString();
  30. hash_end = new TimeSpan(DateTime.Now.Ticks);
  31. hash_diff = hash_start.Subtract(hash_end).Duration();
  32. string hash_search_diff = hash_diff.TotalSeconds.ToString();
  33. Console.WriteLine("create:{0} search:{1}", hash_create_diff, hash_search_diff);
  34. Console.WriteLine();
  35. //dict
  36. Console.WriteLine("dictionary");
  37. Dictionary<int, string> dict = new Dictionary<int, string>();
  38. TimeSpan dict_start = new TimeSpan(DateTime.Now.Ticks);
  39. for (int i = 0; i < MAX; i++)
  40. {
  41. dict.Add(i, i.ToString());
  42. }
  43. TimeSpan dict_end = new TimeSpan(DateTime.Now.Ticks);
  44. TimeSpan dict_diff = dict_start.Subtract(dict_end).Duration();
  45. string dict_create_diff = dict_diff.TotalSeconds.ToString();
  46. //dict search
  47. dict_start = new TimeSpan(DateTime.Now.Ticks);
  48. tmp = dict[0];
  49. dict_end = new TimeSpan(DateTime.Now.Ticks);
  50. dict_diff = dict_start.Subtract(dict_end).Duration();
  51. string dict_search_diff = dict_diff.TotalSeconds.ToString();
  52. Console.WriteLine("create:{0} search:{1}", dict_create_diff, dict_search_diff);
  53. Console.WriteLine();
  54. //list create
  55. Console.WriteLine("list");
  56. TimeSpan list_start = new TimeSpan(DateTime.Now.Ticks);
  57. List<int> l1 = new List<int>();
  58. for (int i = 0; i < MAX; i++)
  59. l1.Add(i);
  60. TimeSpan list_end = new TimeSpan(DateTime.Now.Ticks);
  61. TimeSpan list_diff = list_start.Subtract(list_end).Duration();
  62. string list_create_diff = list_diff.TotalSeconds.ToString();
  63. //list foreach
  64. list_start = new TimeSpan(DateTime.Now.Ticks);
  65. foreach (int i in l1)
  66. {
  67. if (i == MAX)
  68. break;
  69. }
  70. list_end = new TimeSpan(DateTime.Now.Ticks);
  71. list_diff = list_start.Subtract(list_end).Duration();
  72. string list_foreach_diff = list_diff.TotalSeconds.ToString();
  73. Console.WriteLine("create:{0},foreach:{1}", list_create_diff, list_foreach_diff);
  74. Console.WriteLine();
  75. Console.Read();
  76. }
  77. }
  78. }

C#中哈希表与List的比较的更多相关文章

  1. js中哈希表的几种用法总结

    本篇文章只要是对js中哈希表的几种用法进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1. <html> <head> <script type=" ...

  2. Java中哈希表(Hashtable)是如何实现的

    Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...

  3. [转]net中哈希表的使用 Hashtable

    本文转自:http://www.cnblogs.com/gsk99/archive/2011/08/28/2155988.html 以下是PetShop中DBHelper中的使用过程: //创建哈希表 ...

  4. C++ STL中哈希表Map 与 hash_map 介绍

    0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...

  5. C#中哈希表(HashTable)的用法详解以及和Dictionary比较

    1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对, ...

  6. MySQL中哈希表

    也称为散列表 由直接寻址表改进而来.先看直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.加入某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,...,m-1}的 ...

  7. 转 C#中哈希表(HashTable)的用法详解

    看了一遍有关哈希表的文字,作者总结的真是不错 .收藏起来 1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提 ...

  8. C#中哈希表(HashTable)的用法详解

    描述: 哈希表存放 key.values ,key值可以用于快速调取用,values 对应object类型,也就是说所有类型. 实例: 1.HashTable存放学生的成绩 Hashtable ht1 ...

  9. libnids 中哈希表的建立

    //hash.c #include <sys/types.h>#include <sys/time.h>#include <stdio.h>#include < ...

随机推荐

  1. Android类库常用类库一览

    在Android SDK中包括很多包文件,通过了解这些包的功能也有助于了解可以开发的功能. 在Android类库中,各种包写成android.*的方式,重要包的描述如下所示: android.app ...

  2. 蜗牛历险记(二) Web框架(上)

    接上篇所说,本篇主要内容是讲述如何使用Autofac来管理整个平台的生命周期(初级). 一.简述 插件式Web开发的同学应该还会记得PreApplicationStartMethod这个Assembl ...

  3. BZOJ 1588 营业额统计 Splay

    主要操作为Splay中插入节点,查找前驱和后继节点. 1: #include <cstdio> 2: #include <iostream> 3: #include <c ...

  4. 微软职位内部推荐-Senior NLP Scientist & Developer

    微软近期Open的职位: Contact Person: Winnie Wei (wiwe@microsoft.com )Senior Software Development Engineer/NL ...

  5. mybatis generator自动生成 实体类, sqlmap配置文件 详细介绍

    我使用的是Eclipse Luna 装了自己常用的插件, generator也是其中一个推荐下载 MyBatis_Generator_1.3.1.zip离线安装包 <?xml version=& ...

  6. HTML网页中添加音频视频动画...(转)

    在网页中适当嵌入音频和视频能够充分显示网页的多媒体特性,特别是随着宽带网的普及,使得网络广播和网络视频成为现实,网页音频和视频的重要性也日益突显.具体来说,网页音频和视频的嵌入方法主要有三种: 一.b ...

  7. (转)[C++语法] 关键字typedef用法

    转自http://www.cnblogs.com/SweetDream/archive/2006/05/10/395921.html C/C++语言中的typedef相信大家已经不陌生,本文对C/C+ ...

  8. spoj 24

    大数  #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> ...

  9. 学习javascript总结下来的性能优化的小知识(一)

    http://www.cnblogs.com/ctriphire/p/4115525.html http://www.cnblogs.com/xjchenhao/archive/2012/10/22/ ...

  10. C++开发必看 四种强制类型转换的总结

    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. const_cast ...