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

kim*_*l42 0 .net c# ienumerable count

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

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

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

Jon*_*eet 6

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

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

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

使用Skip()/Any()方法将略比使用效率较低的Count()一些收藏品-但可能是很多大型懒序列更有效。(它甚至适用于无限序列,但Count()不会。)

对于列出了效率的差异将取决于有多少项,当然你会跳绳, -如果你需要看是否有“至少有一百万”的项目,然后使用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();
    }
Run Code Online (Sandbox Code Playgroud)

不过这很烦人 :( 请注意,它也不会IIListProvider<T>真正的Count()方法那样优化- 因为这是内部的。