using BenchmarkDotNet.Attributes;
using Apq.Cfg.Ini;
using Apq.Cfg.Xml;
using Apq.Cfg.Yaml;
using Apq.Cfg.Toml;
namespace Apq.Cfg.Benchmarks;
///
/// 删除操作性能基准测试
/// 测试 Remove 操作在不同场景下的性能
///
[Config(typeof(BenchmarkConfig))]
public class RemoveBenchmarks : 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!;
private string _jsonPath = null!;
private string _iniPath = null!;
private string _xmlPath = null!;
private string _yamlPath = null!;
private string _tomlPath = null!;
[Params(20)]
public int KeyCount { get; set; }
public RemoveBenchmarks()
{
_testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgBench_{Guid.NewGuid():N}");
Directory.CreateDirectory(_testDir);
}
[GlobalSetup]
public void Setup()
{
_jsonPath = Path.Combine(_testDir, "config.json");
_iniPath = Path.Combine(_testDir, "config.ini");
_xmlPath = Path.Combine(_testDir, "config.xml");
_yamlPath = Path.Combine(_testDir, "config.yaml");
_tomlPath = Path.Combine(_testDir, "config.toml");
ResetConfigFiles();
CreateCfgInstances();
}
[IterationSetup]
public void IterationSetup()
{
// 每次迭代前重置配置
_jsonCfg?.Dispose();
_iniCfg?.Dispose();
_xmlCfg?.Dispose();
_yamlCfg?.Dispose();
_tomlCfg?.Dispose();
ResetConfigFiles();
CreateCfgInstances();
}
private void ResetConfigFiles()
{
// 生成包含多个键的 JSON 配置
var jsonContent = "{\n";
for (int i = 0; i < KeyCount; i++)
{
jsonContent += $" \"Key{i}\": \"Value{i}\"";
if (i < KeyCount - 1) jsonContent += ",";
jsonContent += "\n";
}
jsonContent += "}";
File.WriteAllText(_jsonPath, jsonContent);
// 生成 INI 配置
var iniContent = "[Data]\n";
for (int i = 0; i < KeyCount; i++)
{
iniContent += $"Key{i}=Value{i}\n";
}
File.WriteAllText(_iniPath, iniContent);
// 生成 XML 配置
var xmlContent = "\n\n \n";
for (int i = 0; i < KeyCount; i++)
{
xmlContent += $" Value{i}\n";
}
xmlContent += " \n";
File.WriteAllText(_xmlPath, xmlContent);
// 生成 YAML 配置
var yamlContent = "Data:\n";
for (int i = 0; i < KeyCount; i++)
{
yamlContent += $" Key{i}: Value{i}\n";
}
File.WriteAllText(_yamlPath, yamlContent);
// 生成 TOML 配置
var tomlContent = "[Data]\n";
for (int i = 0; i < KeyCount; i++)
{
tomlContent += $"Key{i} = \"Value{i}\"\n";
}
File.WriteAllText(_tomlPath, tomlContent);
}
private void CreateCfgInstances()
{
_jsonCfg = new CfgBuilder()
.AddJson(_jsonPath, level: 0, writeable: true, isPrimaryWriter: true)
.Build();
_iniCfg = new CfgBuilder()
.AddIni(_iniPath, level: 0, writeable: true, isPrimaryWriter: true)
.Build();
_xmlCfg = new CfgBuilder()
.AddXml(_xmlPath, level: 0, writeable: true, isPrimaryWriter: true)
.Build();
_yamlCfg = new CfgBuilder()
.AddYaml(_yamlPath, level: 0, writeable: true, isPrimaryWriter: true)
.Build();
_tomlCfg = new CfgBuilder()
.AddToml(_tomlPath, level: 0, writeable: true, isPrimaryWriter: true)
.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 单键删除性能测试
[Benchmark(Baseline = true)]
[BenchmarkCategory("RemoveSingle")]
public void Json_RemoveSingle()
{
_jsonCfg.Remove("Key0");
}
[Benchmark]
[BenchmarkCategory("RemoveSingle")]
public void Ini_RemoveSingle()
{
_iniCfg.Remove("Data:Key0");
}
[Benchmark]
[BenchmarkCategory("RemoveSingle")]
public void Xml_RemoveSingle()
{
_xmlCfg.Remove("Data:Key0");
}
[Benchmark]
[BenchmarkCategory("RemoveSingle")]
public void Yaml_RemoveSingle()
{
_yamlCfg.Remove("Data:Key0");
}
[Benchmark]
[BenchmarkCategory("RemoveSingle")]
public void Toml_RemoveSingle()
{
_tomlCfg.Remove("Data:Key0");
}
#endregion
#region 批量删除性能测试
[Benchmark]
[BenchmarkCategory("RemoveBatch")]
public void Json_RemoveBatch()
{
for (int i = 0; i < KeyCount; i++)
{
_jsonCfg.Remove($"Key{i}");
}
}
[Benchmark]
[BenchmarkCategory("RemoveBatch")]
public void Ini_RemoveBatch()
{
for (int i = 0; i < KeyCount; i++)
{
_iniCfg.Remove($"Data:Key{i}");
}
}
[Benchmark]
[BenchmarkCategory("RemoveBatch")]
public void Xml_RemoveBatch()
{
for (int i = 0; i < KeyCount; i++)
{
_xmlCfg.Remove($"Data:Key{i}");
}
}
[Benchmark]
[BenchmarkCategory("RemoveBatch")]
public void Yaml_RemoveBatch()
{
for (int i = 0; i < KeyCount; i++)
{
_yamlCfg.Remove($"Data:Key{i}");
}
}
[Benchmark]
[BenchmarkCategory("RemoveBatch")]
public void Toml_RemoveBatch()
{
for (int i = 0; i < KeyCount; i++)
{
_tomlCfg.Remove($"Data:Key{i}");
}
}
#endregion
#region 删除不存在的键
[Benchmark]
[BenchmarkCategory("RemoveNonExistent")]
public void Json_RemoveNonExistent()
{
for (int i = 0; i < KeyCount; i++)
{
_jsonCfg.Remove($"NonExistent:Key{i}");
}
}
[Benchmark]
[BenchmarkCategory("RemoveNonExistent")]
public void Ini_RemoveNonExistent()
{
for (int i = 0; i < KeyCount; i++)
{
_iniCfg.Remove($"NonExistent:Key{i}");
}
}
#endregion
#region 删除后保存
[Benchmark]
[BenchmarkCategory("RemoveAndSave")]
public async Task Json_RemoveAndSave()
{
for (int i = 0; i < KeyCount / 2; i++)
{
_jsonCfg.Remove($"Key{i}");
}
await _jsonCfg.SaveAsync();
}
[Benchmark]
[BenchmarkCategory("RemoveAndSave")]
public async Task Ini_RemoveAndSave()
{
for (int i = 0; i < KeyCount / 2; i++)
{
_iniCfg.Remove($"Data:Key{i}");
}
await _iniCfg.SaveAsync();
}
[Benchmark]
[BenchmarkCategory("RemoveAndSave")]
public async Task Xml_RemoveAndSave()
{
for (int i = 0; i < KeyCount / 2; i++)
{
_xmlCfg.Remove($"Data:Key{i}");
}
await _xmlCfg.SaveAsync();
}
[Benchmark]
[BenchmarkCategory("RemoveAndSave")]
public async Task Yaml_RemoveAndSave()
{
for (int i = 0; i < KeyCount / 2; i++)
{
_yamlCfg.Remove($"Data:Key{i}");
}
await _yamlCfg.SaveAsync();
}
[Benchmark]
[BenchmarkCategory("RemoveAndSave")]
public async Task Toml_RemoveAndSave()
{
for (int i = 0; i < KeyCount / 2; i++)
{
_tomlCfg.Remove($"Data:Key{i}");
}
await _tomlCfg.SaveAsync();
}
#endregion
}