上面的图片是我的同事 Bob 今天早上转发给我的。当我看到图片的内容时,我吓了一跳。因为我在写的代码中都使用了 and,在我看来,两者几乎是等价的,没有根本的区别。今天,看到人们提供了测试数据,我似乎应该将 all 替换为以获得最佳解决方案。FindFirstOrDefaultFirstOrDefaultFind
回想起来,我很久以前也在 StackOverFlow 帖子中读到过类似的讨论。结论还在于,的性能明显优于 。我找到了原帖:FindFirstOrDefault
https://stackoverflow.com/questions/14032709/performance-of-find-vs-firstordefault
我发现这是十多年前的帖子!拜托,那还是 .NET Framework 的时代,甚至 .NET Core 1.0 还不存在!今天,我们即将进入 .NET 9 时代。这个结论仍然有效吗?
既然我有疑问,那就来做个真正的测试吧。让我们来演示一下 和 今天之间是否仍然存在如此大的差距。FirstOrDefaultFind
首先,创建一个 .NET 8 控制台项目。
dotnet new console -o TestListApp
然后,通过 NuGet 引入性能测试框架。Benchmark.NET
dotnet add package BenchmarkDotNet
最后,编写代码进行测试:
[MemoryDiagnoser]
public class ListTest
{
[Benchmark]
public int? TestFindInt()
{
var list = new List<int>(5000);
for (int i = 0; i < 5000; i++)
{
list.Add(i);
}
return list.Find(i => i > 1200);
}
[Benchmark]
public int? TestFirstInt()
{
var list = new List<int>(5000);
for (int i = 0; i < 5000; i++)
{
list.Add(i);
}
return list.FirstOrDefault(i => i > 1200);
}
[Benchmark]
public object? TestFindObject()
{
var list = new List<Student>(5000);
for (int i = 0; i < 5000; i++)
{
list.Add(new Student()
{
Id = i + 1,
Name = "Student" + i,
Age = i % 4 + 18
});
}
return list.Find(o => o.Id == 339);
}
[Benchmark]
public object? TestFirstObject()
{
var list = new List<Student>(5000);
for (int i = 0; i < 5000; i++)
{
list.Add(new Student()
{
Id = i+1,
Name="Student"+i,
Age = i%4 + 18
});
}
return list.FirstOrDefault(o => o.Id==339);
}
}
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
internal class Program
{
var summary = BenchmarkRunner.Run\<ListTest>();
Console.WriteLine(summary);
}
运行基准测试,几分钟后我们得到结果,如下所示:
从结果中可以明显看出 确实比 略好。如果代码选择使用 ,则似乎更明智。但是,两种方法之间的性能差异并不那么显着,约为 3-10%。