背景介绍
BenchmarkDotNet是一款强力的.NET性能基准测试库, 官网https://benchmarkdotnet.org/。
运行时支持
- NET Framework (4.6+),
- .NET Core (2.0+)
- Mono
- CoreRT。
BenchmarkDotnet为每个被测试的方法提供了孤立的环境, 使用BenchmarkDotnet, 程序员可以很容易的编写各种性能测试方法,并可以避免许多常见的坑。
代码基准测试(Code Benchmarking)
现在我们希望来对比一下Linq to object中First和Single方法的性能
虽然我们知道First的性能肯定比Single高, First方法会在查询到第一个满足条件的对象之后就停止集合遍历,而Single找到第一个满足条件的对象之后,不会停止查找,它会去继续查找集合中的剩余对象,直到遍历整个集合或者在集合中找到第二个匹配条件的对象。 这里我们只是为了演示一下如何进行代码基准测试。
为了使用BenchmarkDotNet来进行代码基准测试,我们首先创建一个空的.Net Core控制台程序。

然后我们使用Package Manage Console添加BenchmarkDotNet库
PM> Install-Package BenchmarkDotNet
然后我们修改Program.cs文件, 代码如下
public class Program { public class SingleVsFirst { private readonly List<string> _haystack = new List<string>(); private readonly int _haystackSize = 1000000; private readonly string _needle = "needle"; public SingleVsFirst() { //Add a large amount of items to our list. Enumerable.Range(1, _haystackSize).ToList().ForEach(x => _haystack.Add(x.ToString())); //Insert the needle right in the middle. _haystack.Insert(_haystackSize / 2, _needle); } [Benchmark] public string Single() => _haystack.SingleOrDefault(x => x == _needle); [Benchmark] public string First() => _haystack.FirstOrDefault(x => x == _needle); } public static void Main(string[] args) { var summary = BenchmarkRunner.Run<SingleVsFirst>(); Console.ReadLine(); } }代码解释说明
- 以上代码中
SingleVsFirst类是一个测试类。 - 测试类中我们生成了一个拥有100万对象的字符串集合。
- 我们在集合的中间位置插入了一个测试字符串,字符串的内容是"needle"。
- 代码中的
Single和First方法,分别调用了Linq to object的SingleOrDefault和FirstOrDefault方法来查询字符串集合中的"needle"字符串。 - 在
Single和First方法上,我们加入[Benchmark]特性, 拥有该特性的方法会出现在最后的基准检测报告中。
