【问题标题】:.NET HashTable Vs Dictionary - Can the Dictionary be as fast?.NET HashTable Vs Dictionary - 字典可以这么快吗?
【发布时间】:2010-11-08 12:23:01
【问题描述】:

我想弄清楚何时以及为什么要使用 Dictionary 或 HashTable。我在此处进行了一些搜索,发现人们在谈论我完全同意的 Dictionary 的一般优势,这导致了装箱和拆箱优势以获得轻微的性能提升。

但我也读过字典不会总是按照插入的顺序返回对象,它是排序的。 HashTable 会在哪里。据我了解,这导致 HashTable 在某些情况下要快得多。

我的问题是,这些情况可能是什么?我在上面的假设中是错的吗?你可以在什么情况下选择一个高于另一个,(是的,最后一个有点模棱两可)。

【问题讨论】:

  • 我不想对此投赞成票,但你的业力是 7,777,我不想成为那个为你搞砸的人。

标签: c# .net collections dictionary hashtable


【解决方案1】:

我想这对你现在没有任何意义。但仅供路过的人参考

Performance Test - SortedList vs. SortedDictionary vs. Dictionary vs. Hashtable

内存分配:

用于插入的时间:

搜索项目的时间:

【讨论】:

  • @JohnHenckel 不,排序列表的查找速度较慢。更大的性能系数意味着更好的性能和更好的内存使用。因此,根据图表,排序列表的内存使用率最高,但在插入和查找等其他方面却很糟糕。
  • 大家好,很抱歉提出一个基本问题。但是,如果“更大的性能系数”意味着更好的性能,那么从图表来看,看起来 Hashtable 比 Dictionary 更快?如果是,那么为什么人们说 Dictionary 在实践中比 Hastable 快(因为 Dictionary 不使用装箱/拆箱)?
  • 我对图中单位的含义感到困惑。如果 Y 轴是“时间”,则更高的值应该是“更多时间”,但我自己的测试表明 SortedDictionary 比 Dictionary 慢得多。所以,也许添加一条消息“越高越快”
【解决方案2】:

字典具有作为泛型类型的优势,由于不需要装箱,这使其类型安全且速度更快。以下comparison table(使用类似 SO question post 中的答案构建)说明了支持字典而不是哈希表的其他一些原因(反之亦然)。

【讨论】:

    【解决方案3】:

    另一个重要的区别是Hashtable 是线程安全的。 Hashtable 内置了多读取器/单写入器 (MR/SW) 线程安全性,这意味着 Hashtable 允许一个写入器与多个读取器一起使用而无需锁定。在Dictionary 的情况下,没有线程安全,如果您需要线程安全,则必须实现自己的同步。

    进一步阐述:

    Hashtable,通过 Synchronized 属性提供一些线程安全,该属性返回集合周围的线程安全包装。包装器通过在每次添加或删除操作时锁定整个集合来工作。因此,每个试图访问集合的线程都必须等待轮到它来获取一个锁。这是不可扩展的,并且可能导致大型集合的性能显着下降。此外,设计并未完全免受竞争条件的影响。

    .NET Framework 2.0 集合类如List<T>Dictionary<TKey, TValue> 等不提供任何线程同步;当在多个线程上同时添加或删除项目时,用户代码必须提供所有同步 如果您需要类型安全以及线程安全,请使用 .NET Framework 中的并发集合类。在此处进一步阅读。

    【讨论】:

      【解决方案4】:

      MSDN 文章:“Dictionary<TKey, TValue> 类具有相同的 Hashtable 类的功能。一个Dictionary<TKey, TValue> 特定类型(Object 除外)的性能比 Hashtable 用于值类型,因为 Hashtable 的元素是 键入Object,因此,如果出现以下情况,通常会发生装箱和拆箱 存储或检索值类型”。

      链接:http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.90).aspx

      【讨论】:

        【解决方案5】:

        Hashtable 和 Dictionary 的区别

        字典:

        • 如果我们尝试查找不存在的键,字典会返回错误。
        • 字典比 Hashtable 更快,因为没有装箱和拆箱。
        • 字典是一种泛型类型,这意味着我们可以将它与任何数据类型一起使用。

        哈希表:

        • 如果我们尝试查找不存在的键,Hashtable 将返回 null。
        • 哈希表比字典慢,因为它需要装箱和拆箱。
        • Hashtable 不是泛型,

        【讨论】:

          【解决方案6】:

          如果你关心阅读总是按照它们在字典中的插入顺序返回对象,你可以看看

          OrderedDictionary - 可以通过整数索引访问值(按添加项目的顺序) SortedDictionary - 项目自动排序

          【讨论】:

            【解决方案7】:

            字典比哈希表更快,因为字典是一种通用的强类型。 Hashtable 速度较慢,因为它将对象作为数据类型,这会导致装箱和拆箱。

            【讨论】:

            【解决方案8】:

            另一个重要的区别是 Hashtable 类型同时支持无锁的多个读取器和单个写入器,而 Dictionary 不支持。

            【讨论】:

            • 并发字典将支持(.Net 4.0)
            • 我不确定我是否理解这个答案。看这里msdn.microsoft.com/en-us/library/… 它说“为了支持多个写入器,必须通过 Synchronized 方法返回的包装器完成对 Hashtable 的所有操作,前提是没有线程读取 Hashtable 对象。”这似乎使“无锁多个读取器”功能变得毫无用处,所以我们又不得不锁定对 Hashtable 的所有访问,就像使用 Dictionary 一样。
            【解决方案9】:

            System.Collections.Generic.Dictionary<TKey, TValue>System.Collections.Hashtable 类都在内部维护一个哈希表数据结构。 它们都不能保证保持项目的顺序。

            撇开装箱/拆箱问题不谈,大多数情况下,它们应该具有非常相似的性能。

            它们之间的主要结构区别在于 Dictionary 依赖 chaining(维护每个哈希表桶的项目列表)来解决冲突,而 Hashtable 使用 rehashing em> 用于冲突解决(当发生冲突时,尝试另一个哈希函数将密钥映射到存储桶)。

            如果您的目标是 .NET Framework 2.0+,则使用 Hashtable 类几乎没有什么好处。 Dictionary<TKey, TValue> 已经过时了。

            【讨论】:

            • @Jon- 此处深入讨论了链接和重新散列-msdn.microsoft.com/en-us/library/ms379571(VS.80).aspx
            • 谢谢两位。刚刚找到 Richard 发布的那个页面...本来想问一下 Chaining 的问题,但 MSDN 网站实际上很有帮助!
            • @Mehrdad - 我不清楚如何解决冲突是这样的:如果多个键可能导致相同的哈希,那么您如何确保您在查找时获得正确的值,即函数如何知道要返回哪个元素?在msdn.microsoft.com/en-us/library/ms379571%28VS.80%29.aspx 中,它说,“而不是在发生冲突时重新探测,就像 Hashtable 类所做的那样,字典只是将任何冲突链接到存储桶的列表中。”这是否意味着在使用 Dictionary 时,开发人员不必担心冲突?
            • @Howiecamp:这与Hashtable 并没有太大区别。哈希表在一个条目中存储 3 条信息:键哈希、键本身和值。对于具有相等哈希的项目,它必须遍历列表以找到具有相等键的项目并返回其值。 Hashtable 也是如此。作为正常使用Dictionary的开发者,您无需担心。
            • @Mehrdad 明确一点,Hashtable 和 Dictionary 对象都存储密钥本身,并且都对开发人员隐藏了冲突?
            【解决方案10】:

            两者实际上是同一个类(您可以查看反汇编)。 HashTable 是在 .Net 拥有泛型之前首先创建的。然而,Dictionary 是一个通用类,并为您提供强大的打字优势。我永远不会使用 HashTable,因为 Dictionary 不会花费您任何费用。

            【讨论】:

              猜你喜欢
              • 2012-08-07
              • 2011-02-03
              • 2011-02-05
              • 1970-01-01
              • 2011-03-24
              • 1970-01-01
              • 2014-06-06
              • 2019-01-15
              • 2012-04-27
              相关资源
              最近更新 更多