我有一个简单的对象数组:
Contact[] contacts = _contactService.GetAllContacts();
我想测试该方法是否返回任何联系人。我非常喜欢Any()
的LINQ语法,因为它突出了我想要实现的目标:
if(!contacts.Any()) return;
然而,这是否比测试数组的长度慢?
if(contacts.Length == 0) return;
有什么方法可以找出Any()
在这种情况下执行什么样的操作而不必去这里问?类似于Profiler,但是对于内存中的集合?
答案 0 :(得分:6)
有两种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/
答案 1 :(得分:4)
如果您有一个数组,则Length属于数组的属性。调用Any时,您将迭代数组以查找第一个元素。设置枚举器可能比读取Length属性更昂贵。
答案 2 :(得分: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 :(得分:3)
是的,它较慢,因为它遍历元素。使用Length
属性更好。但我仍然认为存在显着的差异,因为Any
一找到项目就会返回 true 。
答案 4 :(得分:3)
我必须完全不同意其他答案。 它肯定不会迭代数组。它会慢一点,因为它需要创建一个数组迭代器对象并调用MoveNext()
一次,但在大多数情况下这个成本应该可以忽略不计;如果Any()
使代码更具可读性,请随意使用。
来源:已解密的Enumerable.Any<TSource>
代码。