【问题标题】:What's the quickest way to check the size of an IEnumerable is greater than some given value?检查 IEnumerable 的大小是否大于某个给定值的最快方法是什么?
【发布时间】:2020-03-09 17:18:57
【问题描述】:

我知道您可以使用enumerable.Any() 而不是enumerable.Count() 来有效地检查集合中是否包含任何内容。

是否有等效的方法来检查尺寸至少是更大的尺寸?

例如,我如何有效地做enumerable.Count() > 3

【问题讨论】:

  • Count() 足够聪明,可以对某些类型使用有效的方法。如List<T>.Count
  • 您也许可以使用ElemantAtOrDefault 并进行空检查,但我会说使用Count 是更好的选择。速度方面的潜在改进(我自己还没有测试过)可能在极小的时间范围内,此时代码可读性应该是您决定的目标。
  • morelinq 拥有AtLeast
  • 如果底层类型没有可以使用的Count 属性,您可以使用enumerable.Skip(size).Any() 来避免迭代整个事物。

标签: c# .net count ienumerable


【解决方案1】:

不幸的是,最有效的方法取决于实施。在这一点上,这是一个泄漏的抽象。

如果您使用List<T> 或类似名称,使用Count() 将是最快的。但是对于任何延迟评估的序列,它将评估整个序列

对于惰性求值的序列,使用enumerable.Skip(3).Any() 会更有效,因为一旦找到第四个元素就可以停止。这就是您需要了解的全部内容;你不关心实际大小。

对于某些集合,使用Skip()/Any() 方法的效率将略低于使用Count() - 但对于大型惰性序列可能要高效得多。 (它甚至适用于无限序列,Count() 不会。)

列表的效率差异当然取决于您跳过了多少项目 - 如果您需要查看是否有“至少一百万”个项目,那么使用 Count() 将是 much 更高效的列表。

很抱歉没有给你一个简单的答案。如果您确实需要在每种情况下都达到最佳状态,您可以执行与 Count() 方法相同的优化。像这样的:

// FIXME: This name is horrible! Note that you'd call it with 4 in your case,
// as it's inclusive of minCount.
// Note this assumes C# 8 and its lovely switch expression support.
// It could be written with if/else etc of course.
public static bool HasAtMinElements<T>(this IEnumerable<T> source, int minCount) =>
    source switch
    {
        null => throw new ArgumentNullException(nameof(source)),
        ICollection<TSource> coll => coll.Count >= minCount,
        ICollection coll => coll.Count >= minCount,
        _ => source.Skip(minCount - 1).Any();
    }

这很烦人 :( 请注意,它也不会像 real Count() method does 那样优化 IIListProvider&lt;T&gt; - 因为那是内部的。

【讨论】:

  • 这也取决于。 List,即支持 Count() 作为超快速实现,但不支持 Where() 上的 Count()。在这里,您遇到了 Count () 或 Any () - Any 不适合除 > 0 之外的任何内容,Count 可能更慢。 Skip(x).Any() 是一个很好的折衷方案。您无法对此进行优化 - 特别是在过滤时 - 但这意味着一旦结果完成,任何执行都可以停止,而不会返回准确的计数。
  • @TomTom: 确实——虽然在列表上调用Select() 仍然不能让你计算结果,即使它和以前一样:( 我'我确信一个高度优化的 LINQ 是可行的,但很难干净地实现。
【解决方案2】:

Enumerable.Count 方法是微软推荐的返回序列中元素数量的方法,这是你已经在做的,据我所知,这是最好的选择。

【讨论】:

  • 实际上并不是按照乔恩的说法。要查看是否有 X 或更多元素 - 计算所有元素可能需要太多时间;)
  • 很公平。总是很高兴得到传奇人物 Jon Skeet 的纠正,因此为您的评论 TomTom 点赞。
猜你喜欢
  • 2011-01-25
  • 2023-03-24
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 2019-09-20
  • 1970-01-01
相关资源
最近更新 更多