使用.first()和.where (). first()的区别
本文关键字:first 区别 使用 where | 更新日期: 2023-09-27 18:17:18
这两者有什么区别吗?
myList.Where(item => item == 0).First();
:
myList.First(item => item == 0);
后一个对我来说更有意义,因为它更短,但我似乎更经常看到顶部的版本。
除了风格偏好,没有别的区别
Where
对不同类型的集合进行了特殊的优化,而其他方法如First
, Single
和Count
没有利用集合的类型。
所以Where(predicate).First()
能够做一些First(predicate)
不能做的优化。
老实说,这是一个糟糕的实现。
看情况。如果LINQ正在转换为一段SQL,那么这取决于如何处理转换。如果你正在使用LINQ对象(例如,你正在查看一个存在于内存数组),那么,虽然最终结果相同,但性能明显不同。我做了一些基准测试,结果让我很惊讶。我本以为array.First()
会比array.Where(...).First()
更有效率,但我发现情况正好相反。
First() = 2655969
Where().First() = 1455211
可以看到,Where().First()
只花费First()
大约一半的时间。
我的基准测试应用程序如下:
class Program
{
private const int internalIterations = 1000;
private const int externalIterations = 100;
private const int dataSize = 100000;
private const int search = dataSize - 1;
private static readonly long[] resultsFirst = new long[externalIterations*2];
private static readonly long[] resultsWhereFirst = new long[externalIterations*2];
private static readonly int[] data = Enumerable.Range(0, dataSize).ToArray();
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < externalIterations; i++)
{
Console.WriteLine("Iteration {0} of {1}", i+1, externalIterations);
sw.Restart();
First();
sw.Stop();
resultsFirst[i*2] = sw.ElapsedTicks;
Console.WriteLine(" First : {0}", sw.ElapsedTicks);
sw.Restart();
WhereFirst();
sw.Stop();
resultsWhereFirst[i*2] = sw.ElapsedTicks;
Console.WriteLine("WhereFirst : {0}", sw.ElapsedTicks);
sw.Restart();
WhereFirst();
sw.Stop();
resultsWhereFirst[(i*2)+1] = sw.ElapsedTicks;
Console.WriteLine("WhereFirst : {0}", sw.ElapsedTicks);
sw.Restart();
First();
sw.Stop();
resultsFirst[(i*2)+1] = sw.ElapsedTicks;
Console.WriteLine(" First : {0}", sw.ElapsedTicks);
}
Console.WriteLine("Done!");
Console.WriteLine("Averages:");
Console.WriteLine(" First Average: {0:0.00}", resultsFirst.Average());
Console.WriteLine("WhereFirst Average: {0:0.00}", resultsWhereFirst.Average());
}
private static void WhereFirst()
{
for (int i = 0; i < internalIterations; i++)
{
int item = data.Where(d => d == search).First();
}
}
private static void First()
{
for (int i = 0; i < internalIterations; i++)
{
int item = data.First(d => d == search);
}
}
}
我尝试使用列表而不是数组作为数据源,发现它更慢。
数据创建行如下:
private static readonly List<int> data = Enumerable.Range(0, dataSize).ToList();
最终结果是:
First() = 3222609
Where().First() = 2124652
不,本地查询没有区别。前一种语法中的Where
是多余的。
"Probably not" -这可能取决于Linq查询是否会被翻译成另一种语言- SQL,例如
在功能上,它们是相同的,但是,单独使用.First(...)
可能更有效。
-
.Where(item => item == 0)
将扫描整个物品列表,并将所有符合标准的物品收集到一个列表中。在该列表上应用.First()
将选择第一项 -
.First(item => item == 0)
有可能扫描列表,直到找到第一个匹配,并在找到第一个匹配后停止。
所以使用.First(item => item == 0)
可能最终会更有效率。
. first()将迭代您的列表,直到找到您的项。. where()将迭代整个列表
所以使用。first()应该更有效。除非你的编译器足够聪明,只执行First().