【问题标题】:How is HashSet<T>.Contains faster than List<T>.Contains?HashSet<T>.Contains 如何比 List<T>.Contains 快?
【发布时间】:2011-12-13 14:59:07
【问题描述】:

我有一个简单的要求:我有数百万个字符串,并且想测试它们是否存在于一个小集合中。我在使用 List&lt;T&gt; 和 HashSet&lt;T&gt; 来设置这个集合之间存在疑问。

当需求相反时,例如你有 100 个字符串并且需要检查它们是否存在于数百万个字符串的集合中,我完全理解HashSet&lt;T&gt; 是最好的选择。

但在我的情况下,.NET 在HashSet&lt;T&gt; 上调用Contains 时似乎必须计算数百万个哈希值(调用GetHashCode),因此调用Contains 的List&lt;T&gt; 可能会更快?

谁能解释这个假设是否正确?

【问题讨论】:

    标签: .net performance list contains hashset


    【解决方案1】:

    我认为 Dictionary 会缓存键的哈希值,并且显然只会计算一次您正在搜索的字符串的哈希值。我要补充一点,如果您的字符串集是静态的并且很少修改,您会发现对不可变列表进行排序并使用 Array.BinarySearch 会更快,但我可能不会这样做,因为它会使代码过于复杂(除非通过对其进行基准测试,我证实它要快得多。)

    【讨论】:

    • 我认为您误解了这个问题。问题是我正在搜索数百万个字符串,因此它无法缓存任何内容。
    • 所以你的问题是:散列一个字符串并通过散列在其他100个字符串中搜索它更快还是通过比较它100次直接搜索?然后你必须对其进行基准测试。我不认为断点是固定的。
    • 我想我找到了一个解决方案:HybridDictionary 类,它会在断点处自动切换。
    • 请注意,此类是前泛型。这显然没有任何意义,但记住这一点很重要
    【解决方案2】:

    这两种方法对我来说都不合适 - HashSet&lt;string&gt; 听起来对我来说可能是最好的方法。

    是的,.NET 必须计算每个字符串的哈希码 - 问题是这是否需要与候选集中的数百个字符串中的每一个检查是否相等。

    根据所有性能问题,您应该真正测试而不是猜测。例如,如果所有字符串都有不同的长度并且它们都很长,那么Equals 对每个候选者来说都是便宜的,而GetHashCode 可能需要很长时间。但是,如果所有字符串的长度都是 10,并且以相同的 6 个字符开头,那么 GetHashCode 将相当便宜,但每个字符串相等性检查都必须检查所有这些常见的前缀字符。哪一个更符合你的实际情况?你的基准显示了什么?您需要多快?

    【讨论】:

    • 很好的答案!我找到了 HybridDictionary 类,您可以在其中将值存储为 null,使其本质上与我猜的 HashSet 相同。
    • @Joshua:如果没有一些具体的性能数据,我不会使用非泛型 HybridDictionary 类(用于将键映射到值,而不仅仅是包含元素)。 List&lt;string&gt; 和 HashSet&lt;string&gt; 对你来说都太慢了吗?请注意,HybridDictionary 不知道切换点在哪里有意义 - 这取决于实际数据,以及 Equals 与 GetHashCode 调用的成本。
    • 我目前使用 HashSet,但有时它包含 3 个值,有时它包含数千个值,所以我正在寻找类似 HybridHashset 的东西,它会在 item-count 时自动切换 >以 100 为例。我知道它永远无法准确计算“100”,但它的估计可能已经足够了。
    • @Joshua:你可以很容易地创建这样一个东西......但是这些字符串有多长?这实际上是性能瓶颈吗?您的绩效目标是什么,HashSet&lt;string&gt; 如何为您工作? (我可能会提供一个示例,说明计算哈希比检查相等即使对于 3 个候选值 更便宜。)
    • @Joshua:我问过几次了——你检查过目前的表现吗?你的基准是怎么说的?如果您还没有获得基准测试,那么肯定还为时过早。永远不要在没有证据的情况下进行优化。
    猜你喜欢
    • 2011-05-01
    • 2013-11-22
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    相关资源
    最近更新 更多