C# LINQ Any vs FirstOrDefault的性能!=无效的

C# LINQ Any vs FirstOrDefault的性能!=无效的,c#,linq,C#,Linq,在我贡献的开源项目(OSP)代码中有多个地方,必须确定集合中的元素是否满足特定条件 我见过在某些情况下使用LINQ表达式Any(lambda表达式)和FirstOrDefault(lambda表达式)!=空,但从未考虑过 我现在已经到了一个地步,我必须对从查询到数据库的集合进行一些迭代,并希望优化运行时 所以我认为FirstOrDefault(lambda表达式)!=null应该比任何(lambda表达式)快,对吗 对于FirstOrDefault(lambda表达式)!=null,迭代(可能)

在我贡献的开源项目(OSP)代码中有多个地方,必须确定集合中的元素是否满足特定条件

我见过在某些情况下使用LINQ表达式
Any(lambda表达式)
FirstOrDefault(lambda表达式)!=空
,但从未考虑过

我现在已经到了一个地步,我必须对从查询到数据库的集合进行一些迭代,并希望优化运行时

所以我认为
FirstOrDefault(lambda表达式)!=null应该比
任何(lambda表达式)
快,对吗

对于
FirstOrDefault(lambda表达式)!=null
,迭代(可能)在找到满足条件的元素时停止(更糟糕的情况是,它迭代整个集合并返回
null

Any(lambda表达式)
的情况下,我认为迭代将继续到集合的末尾,即使找到了满足条件的元素

编辑:杰克逊·波普(Jackson Pope)提到并链接了MSDN的相关文章,但上述说法并不正确


我的想法是正确的还是遗漏了什么?

Any()
中的枚举也会在找到匹配项时停止:


我希望表现会非常相似。请注意,
FirstOrDefault
版本不会与值类型集合一起工作(因为默认值不是null),但是
Any
版本会。

在找到满足条件的元素后,为什么Any应该继续?如果该条件适用于1个元素,则该条件限定为“任意”


我认为它们的性能应该差不多,但任何()都可以更清楚地表达您的意图

你在这里混东西。您谈论的是集合,但您似乎没有使用LINQ访问对象,而是查询数据库

LINQ到对象:
并且应该执行相同的操作,因为它们的代码几乎相同:

FirstOrDefault

foreach (TSource source1 in source)
{
    if (predicate(source1))
        return source1;
}
return default (TSource);
任何

foreach (TSource source1 in source)
{
    if (predicate(source1))
        return true
}
return false;
LINQ到某个数据库:
您正在使用实体框架、LINQ to SQL或NHibernate,并在相应的数据上下文上使用and。
在这种情况下,实际上没有集合,因为这些调用不是在内存中的对象上执行的,而是转换为SQL


这意味着,性能差异源于LINQ提供程序如何将代码转换为SQL,因此最好先检查创建的语句。它们相等吗?或者它们是非常不同的(
从X中选择计数(0)还是从X中选择前1)?那么差异可能在于数据库的查询优化器、索引以及其他方面。

这个问题的问题在于它没有在上下文中被询问。 我提供了一个答案,因为我在代码评审中经常看到这一点,这让我感到困扰。 LINQ不应该成为停止思考的借口

var people = new [] { "Steve", "Joe" };

if (people.Any(s => s == "Joe"))
{
    var joe = people.First(s => s == "Joe");
    // do something with joe
}

// if people is 1,000,000 people and joe is near the end do we want BigO to approach 2N here at worst case ?

var joe1N = people.FirstOrDefault(s => s == "Joe");
if (joe1N != null)
{
    // do something with joe
}

// or do we want to ensure worst case is N by simply using a variable ?
我的两分钱

我在使用Any()时遇到了严重的性能问题。我使用Telerik网格显示相关数据的列表,即

-我有一张“人”的桌子

-“公司”的桌子

-“人民公司”链接表

-“人员控制”链接表

-以及一个“ROL”表,其中包含主类别、子类别和描述

该视图混合了数据,并具有一些属性,可根据需要加载有关特定角色(管理员、报告员、经理)的数据

我的网格使用AJAX,使用“Any”加载需要10秒以上,使用“FirstOrDefault”加载需要3秒或更少。没有花时间调试它,因为需要拦截来自telerik组件和我的模型的调用

希望这有助于。。。所以好好测试一下:)

我们可以使用.Count(x=>x…)!=0而不是使用.Any(x=>x…)或.FirstOrDefault(x=>x…)!=空

 (@p__linq__0 varchar(8000))SELECT TOP (1) 
[Extent1].[Col_1] AS [Col_1], 
[Extent1].[Col_2] AS [Col_2], 
...
[Extent1].[Col_n] AS [Col_n]
FROM [dbo].[Table_X] AS [Extent1]
WHERE [Extent1].[Col_1] = @p__linq__0
因为Linq的查询生成如下所示

(在Any()中,我认为第二个(不存在)条件是不需要。)

.Any(x=>x.Col\u 1=='xxx')

.FirstOrDefault(x=>x.Col_1=='xxx')!=空

 (@p__linq__0 varchar(8000))SELECT TOP (1) 
[Extent1].[Col_1] AS [Col_1], 
[Extent1].[Col_2] AS [Col_2], 
...
[Extent1].[Col_n] AS [Col_n]
FROM [dbo].[Table_X] AS [Extent1]
WHERE [Extent1].[Col_1] = @p__linq__0
.Count(x=>x.Col\u 1=='xxx')!=0

  (@p__linq__0 varchar(8000))SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[Table_X] AS [Extent1]
    WHERE [Extent1].[Col_1] = @p__linq__0
)  AS [GroupBy1]

尽管它有类似的实现,但我认为Any的速度要快一点,因为它不必返回对象,在某些情况下,对象的状态和行为可能很丰富,这取决于查询的考虑程度。

因此,当您想知道是否存在满足指定条件的对象时,是否使用
Any()
,但是
FirstorDefault()
如果你真的想要那个对象回来?@Chris:是的,我就是这么用的。那为什么
FirstorDefault(lambda表达式)!=空
更快?完成了一些
Ticks
测试和
FirstOrDefault(lambda表达式)!=null
总是结束得更快。@Jimi您必须向我们展示您的测试代码。很难做到正确。@AakashM它涉及到对数据库的查询,因此即使发布代码,您也无法对其进行测试。“在
Any(lambda表达式)
的情况下,即使找到了满足条件的元素,我想迭代仍会继续到集合的末尾”。为什么?因为我没有读杰克逊·波普提到的MSDN文章。lolnor没有——我只是没有理由认为LINQ实现是荒谬的。我的问题不是表达意图和代码可读性,而是运行时性能。Any()更干净,但FirstOrDefault()通常会尝试返回找到的第一个项目,因此从技术上讲,它会占用带宽和不需要的返回数据。实际上,LINQ中的优化可能会阻止这种情况的发生,但您想依赖于它吗?这里有一个要点。我们使用实体进行数据库查询,并将表存储在集合中。然后我们迭代这些集合,用LINQ提取我们想要的数据。@Jimi:我不理解你的co
  (@p__linq__0 varchar(8000))SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[Table_X] AS [Extent1]
    WHERE [Extent1].[Col_1] = @p__linq__0
)  AS [GroupBy1]