| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- using BenchmarkDotNet.Attributes;
- namespace Apq.Cfg.Benchmarks;
- /// <summary>
- /// 类型转换性能基准测试
- /// 测试 Get<T> 不同类型转换的性能开销
- /// </summary>
- [Config(typeof(BenchmarkConfig))]
- public class TypeConversionBenchmarks : IDisposable
- {
- private readonly string _testDir;
- private ICfgRoot _cfg = null!;
- public TypeConversionBenchmarks()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgBench_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- }
- [GlobalSetup]
- public void Setup()
- {
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Types": {
- "String": "HelloWorld",
- "LongString": "This is a very long string value that contains many characters to test string handling performance in the configuration system",
- "Int": "12345",
- "Long": "9223372036854775807",
- "Double": "3.14159265358979",
- "Decimal": "12345.6789012345",
- "Bool": "true",
- "BoolFalse": "false",
- "Guid": "550e8400-e29b-41d4-a716-446655440000",
- "DateTime": "2024-12-24T12:00:00",
- "Enum": "Warning",
- "NullableInt": "42",
- "EmptyString": "",
- "Whitespace": " ",
- "Unicode": "你好世界🌍",
- "SpecialChars": "Hello:World=Test\"Quote'Single"
- }
- }
- """);
- _cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- }
- [GlobalCleanup]
- public void Cleanup()
- {
- Dispose();
- }
- public void Dispose()
- {
- _cfg?.Dispose();
- if (Directory.Exists(_testDir))
- {
- Directory.Delete(_testDir, true);
- }
- }
- #region 基础类型转换
- /// <summary>
- /// 获取字符串(无转换,作为基准)
- /// </summary>
- [Benchmark(Baseline = true)]
- [BenchmarkCategory("BasicTypes")]
- public string? Get_String()
- {
- return _cfg.Get("Types:String");
- }
- /// <summary>
- /// 获取字符串(泛型方式)
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public string? Get_String_Generic()
- {
- return _cfg.Get<string>("Types:String");
- }
- /// <summary>
- /// 获取整数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public int Get_Int()
- {
- return _cfg.Get<int>("Types:Int");
- }
- /// <summary>
- /// 获取长整数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public long Get_Long()
- {
- return _cfg.Get<long>("Types:Long");
- }
- /// <summary>
- /// 获取双精度浮点数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public double Get_Double()
- {
- return _cfg.Get<double>("Types:Double");
- }
- /// <summary>
- /// 获取十进制数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public decimal Get_Decimal()
- {
- return _cfg.Get<decimal>("Types:Decimal");
- }
- /// <summary>
- /// 获取布尔值
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("BasicTypes")]
- public bool Get_Bool()
- {
- return _cfg.Get<bool>("Types:Bool");
- }
- #endregion
- #region 复杂类型转换
- /// <summary>
- /// 获取 Guid
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("ComplexTypes")]
- public Guid Get_Guid()
- {
- return _cfg.Get<Guid>("Types:Guid");
- }
- /// <summary>
- /// 获取 DateTime
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("ComplexTypes")]
- public DateTime Get_DateTime()
- {
- return _cfg.Get<DateTime>("Types:DateTime");
- }
- /// <summary>
- /// 获取枚举值
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("ComplexTypes")]
- public LogLevel Get_Enum()
- {
- return _cfg.Get<LogLevel>("Types:Enum");
- }
- /// <summary>
- /// 获取可空整数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("ComplexTypes")]
- public int? Get_NullableInt()
- {
- return _cfg.Get<int?>("Types:NullableInt");
- }
- #endregion
- #region 批量类型转换
- /// <summary>
- /// 批量获取整数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Batch")]
- public void Get_Int_Multiple()
- {
- for (int i = 0; i < 1000; i++)
- {
- _ = _cfg.Get<int>("Types:Int");
- }
- }
- /// <summary>
- /// 批量获取布尔值
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Batch")]
- public void Get_Bool_Multiple()
- {
- for (int i = 0; i < 1000; i++)
- {
- _ = _cfg.Get<bool>("Types:Bool");
- }
- }
- /// <summary>
- /// 批量获取双精度浮点数
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Batch")]
- public void Get_Double_Multiple()
- {
- for (int i = 0; i < 1000; i++)
- {
- _ = _cfg.Get<double>("Types:Double");
- }
- }
- /// <summary>
- /// 批量获取字符串
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Batch")]
- public void Get_String_Multiple()
- {
- for (int i = 0; i < 1000; i++)
- {
- _ = _cfg.Get("Types:String");
- }
- }
- #endregion
- #region 特殊值处理
- /// <summary>
- /// 获取长字符串
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("SpecialValues")]
- public string? Get_LongString()
- {
- return _cfg.Get("Types:LongString");
- }
- /// <summary>
- /// 获取 Unicode 字符串
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("SpecialValues")]
- public string? Get_Unicode()
- {
- return _cfg.Get("Types:Unicode");
- }
- /// <summary>
- /// 获取包含特殊字符的字符串
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("SpecialValues")]
- public string? Get_SpecialChars()
- {
- return _cfg.Get("Types:SpecialChars");
- }
- /// <summary>
- /// 获取空字符串
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("SpecialValues")]
- public string? Get_EmptyString()
- {
- return _cfg.Get("Types:EmptyString");
- }
- #endregion
- #region TryGet 扩展方法
- /// <summary>
- /// TryGet 成功场景
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Extensions")]
- public bool TryGet_Success()
- {
- return _cfg.TryGet<int>("Types:Int", out _);
- }
- /// <summary>
- /// TryGet 失败场景
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Extensions")]
- public bool TryGet_Failure()
- {
- return _cfg.TryGet<int>("Types:NonExistent", out _);
- }
- /// <summary>
- /// GetRequired 成功场景
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Extensions")]
- public int GetRequired_Success()
- {
- return _cfg.GetRequired<int>("Types:Int");
- }
- /// <summary>
- /// GetOrDefault 存在键场景
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Extensions")]
- public int GetOrDefault_ExistingKey()
- {
- return _cfg.GetOrDefault("Types:Int", 0);
- }
- /// <summary>
- /// GetOrDefault 不存在键场景
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Extensions")]
- public int GetOrDefault_NonExistingKey()
- {
- return _cfg.GetOrDefault("Types:NonExistent", 100);
- }
- #endregion
- #region 混合类型操作
- /// <summary>
- /// 混合读取多种类型
- /// </summary>
- [Benchmark]
- [BenchmarkCategory("Mixed")]
- public void Get_MixedTypes()
- {
- for (int i = 0; i < 100; i++)
- {
- _ = _cfg.Get("Types:String");
- _ = _cfg.Get<int>("Types:Int");
- _ = _cfg.Get<bool>("Types:Bool");
- _ = _cfg.Get<double>("Types:Double");
- _ = _cfg.Get<long>("Types:Long");
- }
- }
- #endregion
- }
- /// <summary>
- /// 用于枚举转换测试的日志级别
- /// </summary>
- public enum LogLevel
- {
- Debug,
- Info,
- Warning,
- Error,
- Fatal
- }
|