介绍
今天在测试某些LinQ函数的性能差异时,我注意到LastOrDefault(predicate)
比FirstOrDefault(predicate)
几乎总是更快,这引起了我的兴趣,因此我编写了一些测试用例来测试两个函数之间的差异。
我创建了一个包含从1到1000000的整数
值的列表,如下所示:
List<int> l = new List<int>();
for (int i = 1; i <= 1000000; i++)
{
l.Add(i);
}
然后编写了两种方法first()
和last()
static void first(List<int> l)
{
int e = l.FirstOrDefault(x => x == 500000);
int z = l.FirstOrDefault(x => x == 500000);
int d = l.FirstOrDefault(x => x == 500000);
int v = l.FirstOrDefault(x => x == 500000);
int f = l.FirstOrDefault(x => x == 500000);
}
我将其放在一个for循环中运行1000次,并设置断点条件,在最后一次迭代后停止,但在我测试的每种情况下,LastOrDefault
都更快。
测试用例
- 两者都设置为列表中间的元素(
LastOrDefault
几乎是First
的两倍快) - 两者都设置为列表内相同距离的元素(如250k和750k)-再次
LastOrDefault
更快 - 交换我的方法调用顺序(先调用
Last()
再调用First()
)- 没有区别 - 在它们自己的列表中运行而不是在同一个列表上运行(仍然没有区别)
- 运行一个,关闭应用程序,重新打开,运行另一个(仍然
LastOrDefault
更快) - 将谓词设置为不在列表中的元素(仍然是一样的)
- 将谓词更改为多个合格对象(仍然是一样的)
创建一个降序列表而不是升序列表(没有区别)
.Net Core版本:3.0
由于调试器可能不准确,我尝试了以下代码:
Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);
for (int i = 0; i < 1000; i++)
{
first(l);
}
Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);
for (int i = 0; i < 1000; i++)
{
last(l);
}
Console.WriteLine(DateTime.Now + ":" + DateTime.Now.Millisecond);
在我的所有测试案例中,为什么LastOrDefault
比FirstOrDefault
快得那么明显呢?此外,FirstOrDefault
返回了34秒,而LastOrDefault
返回了23秒。
问题
为什么在我的所有测试案例中,LastOrDefault
都比FirstOrDefault
快得那么明显?
0..end
或者end..0
。没有其他的区别。 - Patrick HofmanLast
的优化,而且Last
需要大约两倍的时间,正如你所预期的那样,但我在.NET Core中看到与OP相同的情况。 - Rawling