C# LinqWhere(表达式).FirstorDefault() 与 .FirstOrDefault(表达式)

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

这两个 Linq 查询有什么区别:

var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault();
// vs.
var result = ResultLists().FirstOrDefault( c => c.code == "abc");
  • 语义完全一样吗?
  • 如果语义上相等,FirstOrDefault
    谓词形式是否比
    Where()
    加上普通的
    FirstOrDefault()
    提供任何理论或实践性能优势?
c# .net performance linq predicate
5个回答
46
投票

两者都可以。

它们都懒惰地运行 - 如果源列表有一百万个项目,但第十个项目匹配,那么两者都只会从源中迭代 10 个项目。

性能应该几乎相同,任何差异都完全微不足道。


16
投票

第二个。 在所有其他条件相同的情况下,第二种情况下的迭代器可以在找到匹配项后立即停止,而第一个迭代器必须找到所有匹配项,然后选择其中的第一个。


8
投票

讨论得很好,以上答案都是正确的。

我没有运行任何性能测试,而根据我的经验,FirstOrDefault() 有时比Where().FirstOrDefault() 更快并且优化。

我最近修复了内存溢出/性能问题(“神经网络算法”),修复方法是将Where(x->...).FirstOrDefault()更改为简单的FirstOrDefault(x->..)。

我忽略了编辑将Where(x->...).FirstOrDefault()更改为简单的FirstOrDefault(x->..)的建议。

所以我相信上述问题的正确答案是

第二种选择是所有情况下的最佳方法


1
投票

Where
实际上是延迟执行 - 这意味着表达式的计算被延迟,直到实际需要其实现的值为止。它通过避免不必要的执行来极大地提高性能。

Where
看起来有点像这样,并返回一个新的 IEnumerable

foreach (var item in enumerable)
{
    if (condition)
    {
        yield return item;
    }
}

FirstOrDefault()
返回
<T>
并且不抛出任何异常或在没有结果时返回null


0
投票

这是我的基准。

公共类 LinqBenchmarks {在此处输入图像描述 私有 int[] _numbers;

    [GlobalSetup]
    public void Setup()
    {
        _numbers = Enumerable.Range(1, 1000).ToArray();
    }


    [Benchmark]
    public int FirstOrDefaultCondition()
    {
        return _numbers.FirstOrDefault(n => n == 800);
    }

    [Benchmark]
    public int WhereFirstOrDefault()
    {
        return _numbers.Where(n => n == 800).FirstOrDefault();
    }

}

所以看起来Where(n => n ==800).FirstOrDefault()比FirstOrDefault(n => n == 800)更快。

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