我只想知道HashSet hs
是否为空。
我并不想知道它包含多少元素。
所以我可以用这个:
bool isEmpty = (hs.Count == 0);
......或者这个:
bool isEmpty = hs.Any(x=>true);
哪一个提供更好的结果,性能方面(特别是当HashSet包含大量元素时)?
答案 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
在这里没有任何意义。你可以把它留下来。