基本数组 Any() 与 Length

问题描述 投票:0回答:6

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

Contact[] contacts = _contactService.GetAllContacts();

我想测试该方法是否返回any联系人。我真的很喜欢

Any()
的 LINQ 语法,因为它突出了我想要实现的目标:

if(!contacts.Any()) return;

但是,这比仅仅测试数组的长度慢吗?

if(contacts.Length == 0) return;

有什么方法可以让我知道

Any()
在这种情况下执行什么样的操作,而不必去这里询问?类似于 Profiler,但用于内存中的集合?

c# linq linq-to-objects
6个回答
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()
once,但在大多数情况下该成本应该可以忽略不计;如果
Any()
使代码对您来说更具可读性,请随意使用它。

来源:反编译

Enumerable.Any<TSource>
代码。


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


0
投票

我刚刚运行了一个 BenchmarkDotNet 项目,该项目测量 100 元素 int 数组的

Any()
Length > 0
,结果是:

方法 意思是 错误 标准偏差 已分配
任何 5.5362 纳秒 1.0495 纳秒 0.0575 纳秒 -
长度 0.2413纳秒 0.1316 纳秒 0.0072 纳秒 -

速度快了 30 倍。

附注实际上,如果您在 Visual Studio 中启用“代码分析器”,它实际上会告诉您“为了清晰起见和性能,更喜欢将‘长度’与 0 进行比较而不是使用‘Any()’@

P.P.S。我正在使用

.NET 8

© www.soinside.com 2019 - 2024. All rights reserved.