HashSet <t>如何。包含比List <t>更快.Contains?</t> </t>

时间:2011-10-23 16:25:59

标签: .net performance list contains hashset

我有一个简单的要求:我有数百万个字符串,并想测试它们是否存在于一个小集合中。我对使用List<T>HashSet<T>这个集合之间存在疑问。

当要求相反时,例如,你有100个字符串,需要检查它们是否存在于数百万个字符串中,我完全理解HashSet<T>是最佳选择。

但就我而言,似乎.NET在GetHashCode上调用Contains时需要计算数百万个哈希值(调用HashSet<T>),因此调用Contains一个List<T>可能会更快吗?

有人能解释这个假设是否正确吗?

2 个答案:

答案 0 :(得分:10)

这些似乎都不适合我 - HashSet<string>听起来对我来说可能是最好的方法。

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

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

答案 1 :(得分:2)

我认为Dictionary会缓存键的哈希值,显然只会计算一次你正在搜索的字符串的哈希值。我将补充说,如果你的字符串集是静态的并且很少被修改,你可以更快地找到对不可变列表进行排序并使用Array.BinarySearch,但可能我不会这样做因为它会使代码太复杂(除非通过对它进行基准测试,我确认它更快。)