.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的协助也能实现强大的查询

相关文章
相关标签/搜索