| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- using System.Text;
- using System.Text.Json;
- using BenchmarkDotNet.Attributes;
- using Apq.Cfg.Ini;
- using Apq.Cfg.Xml;
- using Apq.Cfg.Yaml;
- using Apq.Cfg.Toml;
- namespace Apq.Cfg.Benchmarks;
- /// <summary>
- /// 大文件加载性能基准测试
- /// 测试不同配置源加载大量配置项的性能
- /// </summary>
- [Config(typeof(BenchmarkConfig))]
- public class LargeFileBenchmarks : IDisposable
- {
- private readonly string _testDir;
- [Params(1000)]
- public int ItemCount { get; set; }
- private string _jsonPath = null!;
- private string _iniPath = null!;
- private string _xmlPath = null!;
- private string _yamlPath = null!;
- private string _tomlPath = null!;
- public LargeFileBenchmarks()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgBench_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- }
- [GlobalSetup]
- public void Setup()
- {
- _jsonPath = Path.Combine(_testDir, $"large_{ItemCount}.json");
- _iniPath = Path.Combine(_testDir, $"large_{ItemCount}.ini");
- _xmlPath = Path.Combine(_testDir, $"large_{ItemCount}.xml");
- _yamlPath = Path.Combine(_testDir, $"large_{ItemCount}.yaml");
- _tomlPath = Path.Combine(_testDir, $"large_{ItemCount}.toml");
- GenerateJsonFile(_jsonPath, ItemCount);
- GenerateIniFile(_iniPath, ItemCount);
- GenerateXmlFile(_xmlPath, ItemCount);
- GenerateYamlFile(_yamlPath, ItemCount);
- GenerateTomlFile(_tomlPath, ItemCount);
- }
- [GlobalCleanup]
- public void Cleanup()
- {
- Dispose();
- }
- public void Dispose()
- {
- if (Directory.Exists(_testDir))
- {
- Directory.Delete(_testDir, true);
- }
- }
- #region 文件生成方法
- private static void GenerateJsonFile(string path, int count)
- {
- var data = new Dictionary<string, object>();
- for (int i = 0; i < count; i++)
- {
- var section = $"Section{i / 10}";
- if (!data.ContainsKey(section))
- {
- data[section] = new Dictionary<string, object>();
- }
- ((Dictionary<string, object>)data[section])[$"Key{i}"] = $"Value{i}";
- }
- File.WriteAllText(path, JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }));
- }
- private static void GenerateIniFile(string path, int count)
- {
- var sb = new StringBuilder();
- var currentSection = -1;
- for (int i = 0; i < count; i++)
- {
- var section = i / 10;
- if (section != currentSection)
- {
- currentSection = section;
- sb.AppendLine($"[Section{section}]");
- }
- sb.AppendLine($"Key{i}=Value{i}");
- }
- File.WriteAllText(path, sb.ToString());
- }
- private static void GenerateXmlFile(string path, int count)
- {
- var sb = new StringBuilder();
- sb.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
- sb.AppendLine("<configuration>");
- var currentSection = -1;
- for (int i = 0; i < count; i++)
- {
- var section = i / 10;
- if (section != currentSection)
- {
- if (currentSection >= 0)
- {
- sb.AppendLine($" </Section{currentSection}>");
- }
- currentSection = section;
- sb.AppendLine($" <Section{section}>");
- }
- sb.AppendLine($" <Key{i}>Value{i}</Key{i}>");
- }
- if (currentSection >= 0)
- {
- sb.AppendLine($" </Section{currentSection}>");
- }
- sb.AppendLine("</configuration>");
- File.WriteAllText(path, sb.ToString());
- }
- private static void GenerateYamlFile(string path, int count)
- {
- var sb = new StringBuilder();
- var currentSection = -1;
- for (int i = 0; i < count; i++)
- {
- var section = i / 10;
- if (section != currentSection)
- {
- currentSection = section;
- sb.AppendLine($"Section{section}:");
- }
- sb.AppendLine($" Key{i}: Value{i}");
- }
- File.WriteAllText(path, sb.ToString());
- }
- private static void GenerateTomlFile(string path, int count)
- {
- var sb = new StringBuilder();
- var currentSection = -1;
- for (int i = 0; i < count; i++)
- {
- var section = i / 10;
- if (section != currentSection)
- {
- currentSection = section;
- sb.AppendLine($"[Section{section}]");
- }
- sb.AppendLine($"Key{i} = \"Value{i}\"");
- }
- File.WriteAllText(path, sb.ToString());
- }
- #endregion
- #region 加载性能测试
- [Benchmark(Baseline = true)]
- [BenchmarkCategory("Load")]
- public void Json_Load()
- {
- using var cfg = new CfgBuilder()
- .AddJson(_jsonPath, level: 0, writeable: false)
- .Build();
- }
- [Benchmark]
- [BenchmarkCategory("Load")]
- public void Ini_Load()
- {
- using var cfg = new CfgBuilder()
- .AddIni(_iniPath, level: 0, writeable: false)
- .Build();
- }
- [Benchmark]
- [BenchmarkCategory("Load")]
- public void Xml_Load()
- {
- using var cfg = new CfgBuilder()
- .AddXml(_xmlPath, level: 0, writeable: false)
- .Build();
- }
- [Benchmark]
- [BenchmarkCategory("Load")]
- public void Yaml_Load()
- {
- using var cfg = new CfgBuilder()
- .AddYaml(_yamlPath, level: 0, writeable: false)
- .Build();
- }
- [Benchmark]
- [BenchmarkCategory("Load")]
- public void Toml_Load()
- {
- using var cfg = new CfgBuilder()
- .AddToml(_tomlPath, level: 0, writeable: false)
- .Build();
- }
- #endregion
- #region 加载后读取性能测试
- [Benchmark]
- [BenchmarkCategory("LoadAndRead")]
- public string? Json_LoadAndRead()
- {
- using var cfg = new CfgBuilder()
- .AddJson(_jsonPath, level: 0, writeable: false)
- .Build();
- return cfg.Get($"Section{ItemCount / 20}:Key{ItemCount / 2}");
- }
- [Benchmark]
- [BenchmarkCategory("LoadAndRead")]
- public string? Ini_LoadAndRead()
- {
- using var cfg = new CfgBuilder()
- .AddIni(_iniPath, level: 0, writeable: false)
- .Build();
- return cfg.Get($"Section{ItemCount / 20}:Key{ItemCount / 2}");
- }
- [Benchmark]
- [BenchmarkCategory("LoadAndRead")]
- public string? Xml_LoadAndRead()
- {
- using var cfg = new CfgBuilder()
- .AddXml(_xmlPath, level: 0, writeable: false)
- .Build();
- return cfg.Get($"Section{ItemCount / 20}:Key{ItemCount / 2}");
- }
- [Benchmark]
- [BenchmarkCategory("LoadAndRead")]
- public string? Yaml_LoadAndRead()
- {
- using var cfg = new CfgBuilder()
- .AddYaml(_yamlPath, level: 0, writeable: false)
- .Build();
- return cfg.Get($"Section{ItemCount / 20}:Key{ItemCount / 2}");
- }
- [Benchmark]
- [BenchmarkCategory("LoadAndRead")]
- public string? Toml_LoadAndRead()
- {
- using var cfg = new CfgBuilder()
- .AddToml(_tomlPath, level: 0, writeable: false)
- .Build();
- return cfg.Get($"Section{ItemCount / 20}:Key{ItemCount / 2}");
- }
- #endregion
- }
|