HashSet<T> 和 Linq 查询的性能表现

4
上周我收到了一些代码,并被要求提高其性能。因此开始了工作,但很快我发现他们使用了很多的HashSet<T>对象来存储大量的对象(在10000到超过100000个对象之间)。在代码中,他们使用HashSet<T>是出于性能原因。
他们唯一做的事情就是用对象填充HashSet,然后使用一些Linq在多个集合之间执行查询。大多数查询是加入1个或n个HashSet,或者使用First()Where()从集合中检索特定的对象。
我想知道与普通的List<T>相比,我们是否会获得任何性能优势?因为他们在代码中使用的所有Linq扩展方法都是针对IEnumerable<T>编写的。
在互联网上,很多文章说List会更快,但有些说HashSet处理大量集合比List更好。
希望有人能给我更多建议。
谢谢。

2
你不能轻易地编写一个测试来比较这两者的性能吗? - row1
1
我还要指出的是,HashSet 不是有序的 - 取它的 First 元素是错误的,除非你需要一个任意元素,或者已经过滤掉所有但一个元素。 - Kobi
2
你的方法非常低效。使用性能分析器。 - Hans Passant
1个回答

12

如果你只使用LINQ查询,你不会得到任何性能优势,因为你只是枚举整个集合。实际上,由于连续的内部存储,List<T>可能具有更好的性能。

要获得HashSet<T>的性能优势,你需要使用ISet<T>方法,最好配合另一个HashSet<T>使用,因为在代码中可以看出它是针对这种情况进行了优化。此外,只有那些利用成员对象的哈希码,如相等测试等哈希查找的O(1)性能特征的操作才会更快,因为HashSet<T>的性能基于哈希查找的O(1)性能特性。那些不利用成员哈希码的操作,例如根据成员属性而不是成员本身进行过滤,需要执行O(N)操作,与List<T>相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接