| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- using BenchmarkDotNet.Attributes;
- using Apq.Cfg.Ini;
- using Apq.Cfg.Xml;
- using Apq.Cfg.Yaml;
- using Apq.Cfg.Toml;
- namespace Apq.Cfg.Benchmarks;
- /// <summary>
- /// GetSection 性能基准测试
- /// 测试不同配置源的 GetSection/GetChildKeys 操作性能
- /// </summary>
- [Config(typeof(BenchmarkConfig))]
- public class GetSectionBenchmarks : IDisposable
- {
- private readonly string _testDir;
- private ICfgRoot _jsonCfg = null!;
- private ICfgRoot _iniCfg = null!;
- private ICfgRoot _xmlCfg = null!;
- private ICfgRoot _yamlCfg = null!;
- private ICfgRoot _tomlCfg = null!;
- public GetSectionBenchmarks()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgBench_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- }
- [GlobalSetup]
- public void Setup()
- {
- // 创建 JSON 配置文件(包含多层嵌套)
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Database": {
- "Connection": {
- "Host": "localhost",
- "Port": 5432,
- "Name": "testdb"
- },
- "Pool": {
- "MinSize": 5,
- "MaxSize": 100
- }
- },
- "App": {
- "Name": "BenchmarkApp",
- "Version": "1.0.0",
- "Settings": {
- "MaxRetries": 3,
- "Timeout": 30,
- "Enabled": true
- }
- },
- "Logging": {
- "Level": "Info",
- "Output": "Console"
- }
- }
- """);
- _jsonCfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- // 创建 INI 配置文件
- var iniPath = Path.Combine(_testDir, "config.ini");
- File.WriteAllText(iniPath, """
- [Database:Connection]
- Host=localhost
- Port=5432
- Name=testdb
- [Database:Pool]
- MinSize=5
- MaxSize=100
- [App]
- Name=BenchmarkApp
- Version=1.0.0
- [App:Settings]
- MaxRetries=3
- Timeout=30
- Enabled=true
- [Logging]
- Level=Info
- Output=Console
- """);
- _iniCfg = new CfgBuilder()
- .AddIni(iniPath, level: 0, writeable: false)
- .Build();
- // 创建 XML 配置文件
- var xmlPath = Path.Combine(_testDir, "config.xml");
- File.WriteAllText(xmlPath, """
- <?xml version="1.0" encoding="utf-8"?>
- <configuration>
- <Database>
- <Connection>
- <Host>localhost</Host>
- <Port>5432</Port>
- <Name>testdb</Name>
- </Connection>
- <Pool>
- <MinSize>5</MinSize>
- <MaxSize>100</MaxSize>
- </Pool>
- </Database>
- <App>
- <Name>BenchmarkApp</Name>
- <Version>1.0.0</Version>
- <Settings>
- <MaxRetries>3</MaxRetries>
- <Timeout>30</Timeout>
- <Enabled>true</Enabled>
- </Settings>
- </App>
- <Logging>
- <Level>Info</Level>
- <Output>Console</Output>
- </Logging>
- </configuration>
- """);
- _xmlCfg = new CfgBuilder()
- .AddXml(xmlPath, level: 0, writeable: false)
- .Build();
- // 创建 YAML 配置文件
- var yamlPath = Path.Combine(_testDir, "config.yaml");
- File.WriteAllText(yamlPath, """
- Database:
- Connection:
- Host: localhost
- Port: 5432
- Name: testdb
- Pool:
- MinSize: 5
- MaxSize: 100
- App:
- Name: BenchmarkApp
- Version: 1.0.0
- Settings:
- MaxRetries: 3
- Timeout: 30
- Enabled: true
- Logging:
- Level: Info
- Output: Console
- """);
- _yamlCfg = new CfgBuilder()
- .AddYaml(yamlPath, level: 0, writeable: false)
- .Build();
- // 创建 TOML 配置文件
- var tomlPath = Path.Combine(_testDir, "config.toml");
- File.WriteAllText(tomlPath, """
- [Database.Connection]
- Host = "localhost"
- Port = 5432
- Name = "testdb"
- [Database.Pool]
- MinSize = 5
- MaxSize = 100
- [App]
- Name = "BenchmarkApp"
- Version = "1.0.0"
- [App.Settings]
- MaxRetries = 3
- Timeout = 30
- Enabled = true
- [Logging]
- Level = "Info"
- Output = "Console"
- """);
- _tomlCfg = new CfgBuilder()
- .AddToml(tomlPath, level: 0, writeable: false)
- .Build();
- }
- [GlobalCleanup]
- public void Cleanup()
- {
- Dispose();
- }
- public void Dispose()
- {
- _jsonCfg?.Dispose();
- _iniCfg?.Dispose();
- _xmlCfg?.Dispose();
- _yamlCfg?.Dispose();
- _tomlCfg?.Dispose();
- if (Directory.Exists(_testDir))
- {
- Directory.Delete(_testDir, true);
- }
- }
- #region GetSection 性能测试
- [Benchmark(Baseline = true)]
- [BenchmarkCategory("GetSection")]
- public ICfgSection Json_GetSection() => _jsonCfg.GetSection("Database");
- [Benchmark]
- [BenchmarkCategory("GetSection")]
- public ICfgSection Ini_GetSection() => _iniCfg.GetSection("Database");
- [Benchmark]
- [BenchmarkCategory("GetSection")]
- public ICfgSection Xml_GetSection() => _xmlCfg.GetSection("Database");
- [Benchmark]
- [BenchmarkCategory("GetSection")]
- public ICfgSection Yaml_GetSection() => _yamlCfg.GetSection("Database");
- [Benchmark]
- [BenchmarkCategory("GetSection")]
- public ICfgSection Toml_GetSection() => _tomlCfg.GetSection("Database");
- #endregion
- #region GetSection 嵌套访问性能测试
- [Benchmark]
- [BenchmarkCategory("GetSectionNested")]
- public ICfgSection Json_GetSection_Nested() => _jsonCfg.GetSection("Database").GetSection("Connection");
- [Benchmark]
- [BenchmarkCategory("GetSectionNested")]
- public ICfgSection Ini_GetSection_Nested() => _iniCfg.GetSection("Database").GetSection("Connection");
- [Benchmark]
- [BenchmarkCategory("GetSectionNested")]
- public ICfgSection Xml_GetSection_Nested() => _xmlCfg.GetSection("Database").GetSection("Connection");
- [Benchmark]
- [BenchmarkCategory("GetSectionNested")]
- public ICfgSection Yaml_GetSection_Nested() => _yamlCfg.GetSection("Database").GetSection("Connection");
- [Benchmark]
- [BenchmarkCategory("GetSectionNested")]
- public ICfgSection Toml_GetSection_Nested() => _tomlCfg.GetSection("Database").GetSection("Connection");
- #endregion
- #region GetSection + Get 组合性能测试
- [Benchmark]
- [BenchmarkCategory("GetSectionThenGet")]
- public string? Json_GetSection_ThenGet() => _jsonCfg.GetSection("Database:Connection").Get("Host");
- [Benchmark]
- [BenchmarkCategory("GetSectionThenGet")]
- public string? Ini_GetSection_ThenGet() => _iniCfg.GetSection("Database:Connection").Get("Host");
- [Benchmark]
- [BenchmarkCategory("GetSectionThenGet")]
- public string? Xml_GetSection_ThenGet() => _xmlCfg.GetSection("Database:Connection").Get("Host");
- [Benchmark]
- [BenchmarkCategory("GetSectionThenGet")]
- public string? Yaml_GetSection_ThenGet() => _yamlCfg.GetSection("Database:Connection").Get("Host");
- [Benchmark]
- [BenchmarkCategory("GetSectionThenGet")]
- public string? Toml_GetSection_ThenGet() => _tomlCfg.GetSection("Database:Connection").Get("Host");
- #endregion
- #region GetChildKeys 性能测试
- [Benchmark]
- [BenchmarkCategory("GetChildKeys")]
- public string[] Json_GetChildKeys() => _jsonCfg.GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("GetChildKeys")]
- public string[] Ini_GetChildKeys() => _iniCfg.GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("GetChildKeys")]
- public string[] Xml_GetChildKeys() => _xmlCfg.GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("GetChildKeys")]
- public string[] Yaml_GetChildKeys() => _yamlCfg.GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("GetChildKeys")]
- public string[] Toml_GetChildKeys() => _tomlCfg.GetChildKeys().ToArray();
- #endregion
- #region Section GetChildKeys 性能测试
- [Benchmark]
- [BenchmarkCategory("SectionGetChildKeys")]
- public string[] Json_Section_GetChildKeys() => _jsonCfg.GetSection("Database").GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("SectionGetChildKeys")]
- public string[] Ini_Section_GetChildKeys() => _iniCfg.GetSection("Database").GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("SectionGetChildKeys")]
- public string[] Xml_Section_GetChildKeys() => _xmlCfg.GetSection("Database").GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("SectionGetChildKeys")]
- public string[] Yaml_Section_GetChildKeys() => _yamlCfg.GetSection("Database").GetChildKeys().ToArray();
- [Benchmark]
- [BenchmarkCategory("SectionGetChildKeys")]
- public string[] Toml_Section_GetChildKeys() => _tomlCfg.GetSection("Database").GetChildKeys().ToArray();
- #endregion
- #region 直接 Get vs GetSection+Get 对比
- [Benchmark]
- [BenchmarkCategory("DirectVsSection")]
- public string? Json_DirectGet() => _jsonCfg.Get("Database:Connection:Host");
- [Benchmark]
- [BenchmarkCategory("DirectVsSection")]
- public string? Json_SectionGet() => _jsonCfg.GetSection("Database:Connection").Get("Host");
- #endregion
- }
|