检查 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>
,因为那是内部的。
我知道您可以使用 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>
,因为那是内部的。