using BenchmarkDotNet.Attributes; namespace Apq.Cfg.Benchmarks; /// /// 类型转换性能基准测试 /// 测试 Get<T> 不同类型转换的性能开销 /// [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 基础类型转换 /// /// 获取字符串(无转换,作为基准) /// [Benchmark(Baseline = true)] [BenchmarkCategory("BasicTypes")] public string? Get_String() { return _cfg.Get("Types:String"); } /// /// 获取字符串(泛型方式) /// [Benchmark] [BenchmarkCategory("BasicTypes")] public string? Get_String_Generic() { return _cfg.Get("Types:String"); } /// /// 获取整数 /// [Benchmark] [BenchmarkCategory("BasicTypes")] public int Get_Int() { return _cfg.Get("Types:Int"); } /// /// 获取长整数 /// [Benchmark] [BenchmarkCategory("BasicTypes")] public long Get_Long() { return _cfg.Get("Types:Long"); } /// /// 获取双精度浮点数 /// [Benchmark] [BenchmarkCategory("BasicTypes")] public double Get_Double() { return _cfg.Get("Types:Double"); } /// /// 获取十进制数 /// [Benchmark] [BenchmarkCategory("BasicTypes")] public decimal Get_Decimal() { return _cfg.Get("Types:Decimal"); } /// /// 获取布尔值 /// [Benchmark] [BenchmarkCategory("BasicTypes")] public bool Get_Bool() { return _cfg.Get("Types:Bool"); } #endregion #region 复杂类型转换 /// /// 获取 Guid /// [Benchmark] [BenchmarkCategory("ComplexTypes")] public Guid Get_Guid() { return _cfg.Get("Types:Guid"); } /// /// 获取 DateTime /// [Benchmark] [BenchmarkCategory("ComplexTypes")] public DateTime Get_DateTime() { return _cfg.Get("Types:DateTime"); } /// /// 获取枚举值 /// [Benchmark] [BenchmarkCategory("ComplexTypes")] public LogLevel Get_Enum() { return _cfg.Get("Types:Enum"); } /// /// 获取可空整数 /// [Benchmark] [BenchmarkCategory("ComplexTypes")] public int? Get_NullableInt() { return _cfg.Get("Types:NullableInt"); } #endregion #region 批量类型转换 /// /// 批量获取整数 /// [Benchmark] [BenchmarkCategory("Batch")] public void Get_Int_Multiple() { for (int i = 0; i < 1000; i++) { _ = _cfg.Get("Types:Int"); } } /// /// 批量获取布尔值 /// [Benchmark] [BenchmarkCategory("Batch")] public void Get_Bool_Multiple() { for (int i = 0; i < 1000; i++) { _ = _cfg.Get("Types:Bool"); } } /// /// 批量获取双精度浮点数 /// [Benchmark] [BenchmarkCategory("Batch")] public void Get_Double_Multiple() { for (int i = 0; i < 1000; i++) { _ = _cfg.Get("Types:Double"); } } /// /// 批量获取字符串 /// [Benchmark] [BenchmarkCategory("Batch")] public void Get_String_Multiple() { for (int i = 0; i < 1000; i++) { _ = _cfg.Get("Types:String"); } } #endregion #region 特殊值处理 /// /// 获取长字符串 /// [Benchmark] [BenchmarkCategory("SpecialValues")] public string? Get_LongString() { return _cfg.Get("Types:LongString"); } /// /// 获取 Unicode 字符串 /// [Benchmark] [BenchmarkCategory("SpecialValues")] public string? Get_Unicode() { return _cfg.Get("Types:Unicode"); } /// /// 获取包含特殊字符的字符串 /// [Benchmark] [BenchmarkCategory("SpecialValues")] public string? Get_SpecialChars() { return _cfg.Get("Types:SpecialChars"); } /// /// 获取空字符串 /// [Benchmark] [BenchmarkCategory("SpecialValues")] public string? Get_EmptyString() { return _cfg.Get("Types:EmptyString"); } #endregion #region TryGet 扩展方法 /// /// TryGet 成功场景 /// [Benchmark] [BenchmarkCategory("Extensions")] public bool TryGet_Success() { return _cfg.TryGet("Types:Int", out _); } /// /// TryGet 失败场景 /// [Benchmark] [BenchmarkCategory("Extensions")] public bool TryGet_Failure() { return _cfg.TryGet("Types:NonExistent", out _); } /// /// GetRequired 成功场景 /// [Benchmark] [BenchmarkCategory("Extensions")] public int GetRequired_Success() { return _cfg.GetRequired("Types:Int"); } /// /// GetOrDefault 存在键场景 /// [Benchmark] [BenchmarkCategory("Extensions")] public int GetOrDefault_ExistingKey() { return _cfg.GetOrDefault("Types:Int", 0); } /// /// GetOrDefault 不存在键场景 /// [Benchmark] [BenchmarkCategory("Extensions")] public int GetOrDefault_NonExistingKey() { return _cfg.GetOrDefault("Types:NonExistent", 100); } #endregion #region 混合类型操作 /// /// 混合读取多种类型 /// [Benchmark] [BenchmarkCategory("Mixed")] public void Get_MixedTypes() { for (int i = 0; i < 100; i++) { _ = _cfg.Get("Types:String"); _ = _cfg.Get("Types:Int"); _ = _cfg.Get("Types:Bool"); _ = _cfg.Get("Types:Double"); _ = _cfg.Get("Types:Long"); } } #endregion } /// /// 用于枚举转换测试的日志级别 /// public enum LogLevel { Debug, Info, Warning, Error, Fatal }