检查 IEnumerable 的大小是否大于某个给定值的最快方法是什么?

What's the quickest way to check the size of an IEnumerable is greater than some given value?

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

是否有等效的检查尺寸至少是任何更大的尺寸?

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

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

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

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

对于延迟计算的序列,使用 enumerable.Skip(3).Any() 会更有效,因为它可以在找到第四个元素后停止。这就是您需要了解的全部内容;你不关心实际尺寸。

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

列表效率的差异将取决于您跳过了多少项目,当然 - 如果您需要查看是否有 "at least a million" 个项目,那么使用 Count() 将是 很多 对于列表更有效。

很抱歉没有给您一个简单的答案。如果你真的需要它在每种情况下都是最优的,你可以执行与 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<T>,因为那是内部的。