7

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

所以我可以使用这个:

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

...或这个:

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

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

4

3 回答 3

15

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

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

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

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

于 2013-08-14T15:19:50.793 回答
3

HastSet<T>implements ICollection<T>,它有一个Count属性,所以调用Count()只会调用HastSet<T>.Count,我假设这是一个 O(1) 操作(这意味着它实际上不需要计数- 它只返回 的当前大小HashSet)。

Any将迭代直到找到符合条件的项目,然后停止。

因此,在您的情况下,它只会迭代一项,然后停止,因此差异可能可以忽略不计

如果您有一个想要应用的过滤器x => x.IsValid(例如),那么Any肯定更快,因为它Count(x => x.IsValid)会遍历整个集合,而Any一旦找到匹配项就会停止。

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

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

于 2013-08-14T15:19:06.250 回答
0

根据集合的类型,它可能会或可能不会影响性能。那么为什么不直接使用hs.Any(),因为它是专为您需要了解的内容而设计的呢?

并且 lambda 表达式x => true在这里没有任何意义。你可以忽略它。

于 2013-08-14T16:05:19.097 回答