C# 在列表中查找元素:比较 find 和 FirstOrDefault 的性能

作者:微信公众号:【架构师老卢】
9-20 19:23
128

上面的图片是我的同事 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

最后,编写代码进行测试:

  • 创建类文件并编写基准测试代码。ListTest.cs
[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; }
}
  • 打开文件并添加以下代码:Program.cs
internal class Program  
{  
    var summary = BenchmarkRunner.Run\<ListTest>();    
    Console.WriteLine(summary);  
}

结果

运行基准测试,几分钟后我们得到结果,如下所示:

从结果中可以明显看出 确实比 略好。如果代码选择使用 ,则似乎更明智。但是,两种方法之间的性能差异并不那么显着,约为 3-10%。

相关留言评论
昵称:
邮箱:
阅读排行