using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.Configuration;
namespace Apq.Cfg.Benchmarks;
///
/// Microsoft Configuration 转换性能基准测试
/// 测试 ToMicrosoftConfiguration 和 ConfigChanges 的性能
///
[Config(typeof(BenchmarkConfig))]
public class MicrosoftConfigBenchmarks : IDisposable
{
private readonly string _testDir;
private ICfgRoot _cfg = null!;
private IConfigurationRoot _msConfig = null!;
public MicrosoftConfigBenchmarks()
{
_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, """
{
"Database": {
"Host": "localhost",
"Port": 5432,
"Name": "testdb",
"Connection": {
"Timeout": 30,
"MaxRetries": 3
}
},
"App": {
"Name": "BenchmarkApp",
"Version": "1.0.0",
"Settings": {
"MaxRetries": 3,
"Enabled": true
}
},
"Logging": {
"Level": "Info",
"Output": "Console"
}
}
""");
_cfg = new CfgBuilder()
.AddJson(jsonPath, level: 0, writeable: true, isPrimaryWriter: true)
.Build();
// 预先创建一个 Microsoft Configuration 用于读取测试
_msConfig = _cfg.ToMicrosoftConfiguration();
}
[GlobalCleanup]
public void Cleanup()
{
Dispose();
}
public void Dispose()
{
_cfg?.Dispose();
if (Directory.Exists(_testDir))
{
Directory.Delete(_testDir, true);
}
}
#region ToMicrosoftConfiguration 性能测试
///
/// 转换为 Microsoft Configuration(静态快照)
///
[Benchmark(Baseline = true)]
[BenchmarkCategory("ToMsConfig")]
public IConfigurationRoot ToMicrosoftConfiguration_Static()
{
return _cfg.ToMicrosoftConfiguration();
}
///
/// 转换为支持动态重载的 Microsoft Configuration
///
[Benchmark]
[BenchmarkCategory("ToMsConfig")]
public IConfigurationRoot ToMicrosoftConfiguration_Dynamic()
{
return _cfg.ToMicrosoftConfiguration(new Apq.Cfg.Changes.DynamicReloadOptions());
}
///
/// 多次转换(测试缓存效果)
///
[Benchmark]
[BenchmarkCategory("ToMsConfig")]
public void ToMicrosoftConfiguration_Multiple()
{
for (int i = 0; i < 100; i++)
{
_ = _cfg.ToMicrosoftConfiguration();
}
}
#endregion
#region Microsoft Configuration 读取性能对比
///
/// 通过 ICfgRoot 读取
///
[Benchmark]
[BenchmarkCategory("ReadComparison")]
public string? Read_ViaApqCfg()
{
return _cfg.Get("Database:Host");
}
///
/// 通过 IConfigurationRoot 读取
///
[Benchmark]
[BenchmarkCategory("ReadComparison")]
public string? Read_ViaMsConfig()
{
return _msConfig["Database:Host"];
}
///
/// 批量读取对比 - ICfgRoot
///
[Benchmark]
[BenchmarkCategory("ReadComparison")]
public void BatchRead_ViaApqCfg()
{
for (int i = 0; i < 100; i++)
{
_ = _cfg.Get("Database:Host");
_ = _cfg.Get("Database:Port");
_ = _cfg.Get("App:Name");
}
}
///
/// 批量读取对比 - IConfigurationRoot
///
[Benchmark]
[BenchmarkCategory("ReadComparison")]
public void BatchRead_ViaMsConfig()
{
for (int i = 0; i < 100; i++)
{
_ = _msConfig["Database:Host"];
_ = _msConfig["Database:Port"];
_ = _msConfig["App:Name"];
}
}
#endregion
#region ConfigChanges 订阅性能测试
///
/// 订阅配置变更
///
[Benchmark]
[BenchmarkCategory("ConfigChanges")]
public void Subscribe_ConfigChanges()
{
using var subscription = _cfg.ConfigChanges.Subscribe(_ => { });
}
///
/// 订阅并触发变更
///
[Benchmark]
[BenchmarkCategory("ConfigChanges")]
public void Subscribe_AndTriggerChange()
{
int changeCount = 0;
using var subscription = _cfg.ConfigChanges.Subscribe(_ => changeCount++);
// 触发变更
_cfg.Set("Temp:Key", "Value");
}
///
/// 多订阅者场景
///
[Benchmark]
[BenchmarkCategory("ConfigChanges")]
public void MultipleSubscribers()
{
var subscriptions = new List();
try
{
// 创建 10 个订阅者
for (int i = 0; i < 10; i++)
{
subscriptions.Add(_cfg.ConfigChanges.Subscribe(_ => { }));
}
// 触发变更
_cfg.Set("Temp:MultiKey", "Value");
}
finally
{
foreach (var sub in subscriptions)
{
sub.Dispose();
}
}
}
#endregion
}