BenchmarkDotNet测试性能
使用BenchmarkDotNet测试System.Text.Json和Newtonsoft.Json的性能
安装BenchmarkDotNet、Newtonsoft.Json
dotnet add package BenchmarkDotNet
dotnet add package Newtonsoft.Json
简单使用情况
public class BenchmarkDemo
{
public readonly List<Element> _datas = new()
{
new Element
{
Id = 0,
Name = "参数一",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"}
}
},
new Element
{
Id = 1,
Name = "参数二",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"},
{"时间2:",$"{DateTime.Now}"},
{"时间3:",$"{DateTime.Now}"},
}
},
new Element
{
Id = 2,
Name = "参数三",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"},
{"时间2:",$"{DateTime.Now}"},
{"时间3:",$"{DateTime.Now}"},
{"时间4:",$"{DateTime.Now}"},
{"时间5:",$"{DateTime.Now}"},
}
}
};
public int CurrentParam { get; set; }
[Benchmark]
public void NewtionsoftTest()
{
_ = JsonConvert.SerializeObject(_datas.Find(d => d.Id == CurrentParam));
}
[Benchmark]
public void TextJsonTest()
{
_ = System.Text.Json.JsonSerializer.Serialize(_datas.Find(d => d.Id == CurrentParam));
}
如上图情况,简单的测试,可以快速的对比出两个组件不同的性能差异。
可以看到,.net 自带的Text.Json性能更高。
使用System.Text.Json作为性能测试基准
只需要在该方法上添加[Benchmark(Baseline = true)]即可。
[Benchmark(Baseline = true)]
public void TextJsonTest()
{
_ = System.Text.Json.JsonSerializer.Serialize(_datas.Find(d => d.Id == CurrentParam));
}
可以看到Ratio的值为1.0,而Newtonsoft.Json超过基准值27%。
查看内存诊断情况。
需要在类上加上特性 [MemoryDiagnoser]
结果中出现了内存诊断的信息。
根据不同的参数进行测试
有时候我们需要对不同的内容进行测试。因此提供了一个特性ParamsSourceAttribute,此特性会从列表中循环获取不同的值,然后改变当前的属性值。
首先定义一个参数列表
public List<int> ParamList => new() { 0, 1, 2 };
然后将每次循环到的值赋给当前对象即可。
[ParamsSource(nameof(ParamList))]
public int CurrentParam { get; set; }
如上图,每个方法都按照列表中的参数进行测试。
完成的测试代码
public class Program
{
public static void Main()
{
var summary = BenchmarkRunner.Run<BenchmarkDemo>();
Console.ReadKey();
}
}
/// <summary>
/// 添加内存诊断。
/// </summary>
[MemoryDiagnoser]
public class BenchmarkDemo
{
public readonly List<Element> _datas = new()
{
new Element
{
Id = 0,
Name = "参数一",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"}
}
},
new Element
{
Id = 1,
Name = "参数二",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"},
{"时间2:",$"{DateTime.Now}"},
{"时间3:",$"{DateTime.Now}"},
}
},
new Element
{
Id = 2,
Name = "参数三",
Tags = new Dictionary<string, string>{
{"时间0:",$"{DateTime.Now}"},
{"时间1:",$"{DateTime.Now}"},
{"时间2:",$"{DateTime.Now}"},
{"时间3:",$"{DateTime.Now}"},
{"时间4:",$"{DateTime.Now}"},
{"时间5:",$"{DateTime.Now}"},
}
}
};
public List<int> ParamList => new() { 0, 1, 2 };
/// <summary>
/// 测试时,用的参数。
/// </summary>
[ParamsSource(nameof(ParamList))]
public int CurrentParam { get; set; }
[Benchmark]
public void NewtionsoftTest()
{
_ = JsonConvert.SerializeObject(_datas.Find(d => d.Id == CurrentParam));
}
/// <summary>
/// 以这个方法的结果为基准线。
/// </summary>
[Benchmark(Baseline = true)]
public void TextJsonTest()
{
_ = System.Text.Json.JsonSerializer.Serialize(_datas.Find(d => d.Id == CurrentParam));
}
}
public class Element
{
public int Id { get; set; }
public string Name { get; set; }
public Dictionary<string, string> Tags { get; set; }
}