基本数组:Any() vs Length

12

我有一个简单的对象数组:

Contact[] contacts = _contactService.GetAllContacts();

我想测试一下这个方法是否返回任何联系人。我真的很喜欢Any()的LINQ语法,因为它突出了我想要实现的目标:

if(!contacts.Any()) return;

然而,这比仅测试数组长度慢吗?

if(contacts.Length == 0) return;

有没有办法可以不用来这里询问,找到Any()在这种情况下执行的操作?像一个面向内存集合的Profiler一样?


1
可能是重复的问题:哪种方法更好:.Any() vs .Count() > 0? - Sadique
1
@al-Khwārizmī,其实不是这样的,我也会问关于Count()和Length的同样问题,我的最终问题仍然存在——我如何知道每个LINQ方法而不必为此去查找? - CodingIntrigue
3
这两种形式都不太可能成为应用性能瓶颈。如果您设定了性能目标、编写了代码并对其进行了性能测试,找到了热点/瓶颈,那么现在是担心是否有其他变体可以提供更好性能的时候了。相反,你应该编写表达你意图的清晰代码。 - Damien_The_Unbeliever
5个回答

8

有两个 Any() 方法: 1. 适用于 IEnumerable<T> 的扩展方法 2. 适用于 IQueryable<T> 的扩展方法

我猜你正在使用适用于 IEnumerable<T> 的扩展方法。它看起来像这样:

public static bool Any<T>(this IEnumerable<T> enumerable)
{
    foreach (var item in enumerable)
    {
        return true;
    }

    return false;
}

基本上,使用Length == 0更快,因为它不涉及为数组创建迭代器。
如果您想查看不是您自己的代码(即已编译的代码),例如Any<T>,则可以使用某种反编译器。Jetbrains免费提供了一个 - http://www.jetbrains.com/decompiler/

6
我必须完全反对其他答案。它肯定不会迭代数组。它的速度稍微慢一些,因为它需要创建一个数组迭代器对象并调用 MoveNext() 一次,但在大多数情况下这个成本应该是可以忽略不计的;如果 Any() 让你的代码更易读,请随意使用它。
来源:反编译 Enumerable.Any 代码。

4

如果你有一个数组,它的长度信息存储在数组的属性中。当调用 Any 方法时,它会迭代整个数组以找到第一个元素。设置枚举器可能比仅读取 Length 属性更加耗时。


4
在您的情况下,Length 稍微更好一些:
  // Just private field test if it's zero or not
  if (contacts.Length == 0) 
    return;

  // Linq overhead could be added: e.g. a for loop 
  // for (int i = 0; i < contains.Length; ++i) 
  //   return true;
  // plus inevitable private field test (i < contains.Length) 
  if (!contacts.Any()) 
    return;

但是这两种方法似乎差别不大。

一般情况下,Any 更好,因为它会在找到第一个匹配项后停止。

 // Itterates until 1st item is found 
 if (contains.Any(x => MyCondition(x)))
   return;

 // Itterates the entire collection 
 if (contains.Select(x => MyCondition(x)).Count() > 0) 
   return;

3

是的,它较慢因为它迭代元素。使用Length属性更好。但我仍然认为没有显著的差异,因为Any在找到一个项目后立即返回true


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接