使用BenchmarkDotNet测试性能

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; }
    }
原文地址:https://www.cnblogs.com/yeqifeng2288/p/14366630.html