空哈希集 - 计数与任何

时间:2013-08-14 15:15:37

标签: c# .net performance hashset

我只想知道HashSet hs是否为空。 我并不想知道它包含多少元素。

所以我可以用这个:

bool isEmpty = (hs.Count == 0);

......或者这个:

bool isEmpty = hs.Any(x=>true);

哪一个提供更好的结果,性能方面(特别是当HashSet包含大量元素时)?

3 个答案:

答案 0 :(得分:11)

在HashSet上,您可以同时使用两者,因为HashSet在内部管理计数。

但是,如果您的数据位于IEnumerable<T>IQueryable<T>对象中,则使用result.Any()优先于result.Count()(两种Linq方法)。

Linq的.Count()将遍历整个Enumerable,.Any()只会查看Enumerable中是否存在任何对象。

<强>更新 只是小补充: 在您使用HashSet的情况下.Count可能更好,因为.Any()需要创建并返回IEmumerator,如果您不打算在您的任何位置使用枚举器,这将是一个小开销代码(foreach,Linq等)。但我认为这将被视为“微优化”。

答案 1 :(得分:3)

HastSet<T>实现ICollection<T>,其Count属性,因此拨打Count()只会调用HastSet<T>.Count,我假设是{ O(1)操作(意味着它实际上不必计算 - 它只返回HashSet的当前大小。)

Any将迭代,直到找到与条件匹配的项目,然后停止。

因此,在您的情况下,它只会迭代一个项目,然后停止,因此差异可能会微不足道

如果您要应用过滤器(例如x => x.IsValid),那么Any 肯定会更快,因为{{1}将迭代整个集合,而Count(x => x.IsValid)会在找到匹配时立即停止。

出于这些原因,我通常更喜欢使用Any而不是Any(),因为它更直接,并避免任何潜在的性能问题。我只会切换到Count()==0,如果它提供的重要性能提升超过Count()==0

请注意,Any()在逻辑上与调用Any(x=>true)相同。这并没有改变你的问题,但没有lambda它看起来更清晰。

答案 2 :(得分:0)

根据收集的类型,它可能会或可能不会影响性能。那么为什么不使用hs.Any(),因为它的设计正是您需要知道的?

lambda表达式x => true在这里没有任何意义。你可以把它留下来。