| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- using Apq.Cfg.DependencyInjection;
- using BenchmarkDotNet.Attributes;
- namespace Apq.Cfg.Benchmarks;
- /// <summary>
- /// 源生成器绑定性能测试
- /// 对比源生成器(零反射)与 ObjectBinder(反射)的性能差异
- /// </summary>
- [MemoryDiagnoser]
- [RankColumn]
- public class SourceGeneratorBenchmarks
- {
- private string _testDir = null!;
- private ICfgRoot _cfg = null!;
- private ICfgSection _simpleSection = null!;
- private ICfgSection _nestedSection = null!;
- private ICfgSection _arraySection = null!;
- private ICfgSection _dictionarySection = null!;
- private ICfgSection _complexSection = null!;
- [GlobalSetup]
- public void Setup()
- {
- _testDir = Path.Combine(Path.GetTempPath(), $"ApqCfgSgBench_{Guid.NewGuid():N}");
- Directory.CreateDirectory(_testDir);
- var jsonPath = Path.Combine(_testDir, "config.json");
- File.WriteAllText(jsonPath, """
- {
- "Simple": {
- "Name": "TestApp",
- "Port": 8080,
- "Enabled": true,
- "Timeout": 30.5,
- "Id": "550e8400-e29b-41d4-a716-446655440000"
- },
- "Nested": {
- "Name": "ParentApp",
- "Database": {
- "Host": "localhost",
- "Port": 5432,
- "Name": "testdb"
- },
- "Cache": {
- "Host": "redis.local",
- "Port": 6379
- }
- },
- "Array": {
- "Tags": {
- "0": "tag1",
- "1": "tag2",
- "2": "tag3",
- "3": "tag4",
- "4": "tag5"
- },
- "Ports": {
- "0": 80,
- "1": 443,
- "2": 8080,
- "3": 8443
- }
- },
- "Dictionary": {
- "Settings": {
- "Key1": "Value1",
- "Key2": "Value2",
- "Key3": "Value3",
- "Key4": "Value4",
- "Key5": "Value5"
- }
- },
- "Complex": {
- "Name": "ComplexApp",
- "Endpoints": {
- "0": {
- "Host": "api1.local",
- "Port": 8001
- },
- "1": {
- "Host": "api2.local",
- "Port": 8002
- },
- "2": {
- "Host": "api3.local",
- "Port": 8003
- }
- },
- "Metadata": {
- "version": "1.0.0",
- "author": "test",
- "description": "A complex configuration"
- }
- }
- }
- """);
- _cfg = new CfgBuilder()
- .AddJson(jsonPath, level: 0, writeable: false)
- .Build();
- _simpleSection = _cfg.GetSection("Simple");
- _nestedSection = _cfg.GetSection("Nested");
- _arraySection = _cfg.GetSection("Array");
- _dictionarySection = _cfg.GetSection("Dictionary");
- _complexSection = _cfg.GetSection("Complex");
- }
- [GlobalCleanup]
- public void Cleanup()
- {
- (_cfg as IDisposable)?.Dispose();
- if (Directory.Exists(_testDir))
- {
- try { Directory.Delete(_testDir, true); }
- catch { }
- }
- }
- // ========== 简单类型绑定对比 ==========
- [Benchmark(Description = "SourceGen_SimpleTypes")]
- [BenchmarkCategory("Simple")]
- public SgSimpleOptions SourceGen_SimpleTypes()
- {
- return SgSimpleOptions.BindFrom(_simpleSection);
- }
- [Benchmark(Description = "Reflection_SimpleTypes")]
- [BenchmarkCategory("Simple")]
- public ReflectionSimpleOptions Reflection_SimpleTypes()
- {
- var options = new ReflectionSimpleOptions();
- ObjectBinder.BindSection(_simpleSection, options);
- return options;
- }
- [Benchmark(Description = "SourceGen_SimpleTypes_100")]
- [BenchmarkCategory("Simple")]
- public SgSimpleOptions SourceGen_SimpleTypes_100()
- {
- SgSimpleOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = SgSimpleOptions.BindFrom(_simpleSection);
- }
- return options;
- }
- [Benchmark(Description = "Reflection_SimpleTypes_100")]
- [BenchmarkCategory("Simple")]
- public ReflectionSimpleOptions Reflection_SimpleTypes_100()
- {
- ReflectionSimpleOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = new ReflectionSimpleOptions();
- ObjectBinder.BindSection(_simpleSection, options);
- }
- return options;
- }
- // ========== 嵌套对象绑定对比 ==========
- [Benchmark(Description = "SourceGen_NestedObject")]
- [BenchmarkCategory("Nested")]
- public SgNestedOptions SourceGen_NestedObject()
- {
- return SgNestedOptions.BindFrom(_nestedSection);
- }
- [Benchmark(Description = "Reflection_NestedObject")]
- [BenchmarkCategory("Nested")]
- public ReflectionNestedOptions Reflection_NestedObject()
- {
- var options = new ReflectionNestedOptions();
- ObjectBinder.BindSection(_nestedSection, options);
- return options;
- }
- [Benchmark(Description = "SourceGen_NestedObject_100")]
- [BenchmarkCategory("Nested")]
- public SgNestedOptions SourceGen_NestedObject_100()
- {
- SgNestedOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = SgNestedOptions.BindFrom(_nestedSection);
- }
- return options;
- }
- [Benchmark(Description = "Reflection_NestedObject_100")]
- [BenchmarkCategory("Nested")]
- public ReflectionNestedOptions Reflection_NestedObject_100()
- {
- ReflectionNestedOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = new ReflectionNestedOptions();
- ObjectBinder.BindSection(_nestedSection, options);
- }
- return options;
- }
- // ========== 数组/列表绑定对比 ==========
- [Benchmark(Description = "SourceGen_Array")]
- [BenchmarkCategory("Array")]
- public SgArrayOptions SourceGen_Array()
- {
- return SgArrayOptions.BindFrom(_arraySection);
- }
- [Benchmark(Description = "Reflection_Array")]
- [BenchmarkCategory("Array")]
- public ReflectionArrayOptions Reflection_Array()
- {
- var options = new ReflectionArrayOptions();
- ObjectBinder.BindSection(_arraySection, options);
- return options;
- }
- [Benchmark(Description = "SourceGen_Array_100")]
- [BenchmarkCategory("Array")]
- public SgArrayOptions SourceGen_Array_100()
- {
- SgArrayOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = SgArrayOptions.BindFrom(_arraySection);
- }
- return options;
- }
- [Benchmark(Description = "Reflection_Array_100")]
- [BenchmarkCategory("Array")]
- public ReflectionArrayOptions Reflection_Array_100()
- {
- ReflectionArrayOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = new ReflectionArrayOptions();
- ObjectBinder.BindSection(_arraySection, options);
- }
- return options;
- }
- // ========== 字典绑定对比 ==========
- [Benchmark(Description = "SourceGen_Dictionary")]
- [BenchmarkCategory("Dictionary")]
- public SgDictionaryOptions SourceGen_Dictionary()
- {
- return SgDictionaryOptions.BindFrom(_dictionarySection);
- }
- [Benchmark(Description = "Reflection_Dictionary")]
- [BenchmarkCategory("Dictionary")]
- public ReflectionDictionaryOptions Reflection_Dictionary()
- {
- var options = new ReflectionDictionaryOptions();
- ObjectBinder.BindSection(_dictionarySection, options);
- return options;
- }
- [Benchmark(Description = "SourceGen_Dictionary_100")]
- [BenchmarkCategory("Dictionary")]
- public SgDictionaryOptions SourceGen_Dictionary_100()
- {
- SgDictionaryOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = SgDictionaryOptions.BindFrom(_dictionarySection);
- }
- return options;
- }
- [Benchmark(Description = "Reflection_Dictionary_100")]
- [BenchmarkCategory("Dictionary")]
- public ReflectionDictionaryOptions Reflection_Dictionary_100()
- {
- ReflectionDictionaryOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = new ReflectionDictionaryOptions();
- ObjectBinder.BindSection(_dictionarySection, options);
- }
- return options;
- }
- // ========== 复杂对象绑定对比 ==========
- [Benchmark(Description = "SourceGen_ComplexObject")]
- [BenchmarkCategory("Complex")]
- public SgComplexOptions SourceGen_ComplexObject()
- {
- return SgComplexOptions.BindFrom(_complexSection);
- }
- [Benchmark(Description = "Reflection_ComplexObject")]
- [BenchmarkCategory("Complex")]
- public ReflectionComplexOptions Reflection_ComplexObject()
- {
- var options = new ReflectionComplexOptions();
- ObjectBinder.BindSection(_complexSection, options);
- return options;
- }
- [Benchmark(Description = "SourceGen_ComplexObject_100")]
- [BenchmarkCategory("Complex")]
- public SgComplexOptions SourceGen_ComplexObject_100()
- {
- SgComplexOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = SgComplexOptions.BindFrom(_complexSection);
- }
- return options;
- }
- [Benchmark(Description = "Reflection_ComplexObject_100")]
- [BenchmarkCategory("Complex")]
- public ReflectionComplexOptions Reflection_ComplexObject_100()
- {
- ReflectionComplexOptions options = null!;
- for (int i = 0; i < 100; i++)
- {
- options = new ReflectionComplexOptions();
- ObjectBinder.BindSection(_complexSection, options);
- }
- return options;
- }
- // ========== BindTo 对比 ==========
- [Benchmark(Description = "SourceGen_BindTo")]
- [BenchmarkCategory("BindTo")]
- public SgSimpleOptions SourceGen_BindTo()
- {
- var options = new SgSimpleOptions();
- SgSimpleOptions.BindTo(_simpleSection, options);
- return options;
- }
- [Benchmark(Description = "Reflection_BindTo")]
- [BenchmarkCategory("BindTo")]
- public ReflectionSimpleOptions Reflection_BindTo()
- {
- var options = new ReflectionSimpleOptions();
- ObjectBinder.BindSection(_simpleSection, options);
- return options;
- }
- }
- // ========== 源生成器配置类(使用 [CfgSection] 特性) ==========
- [CfgSection]
- public partial class SgSimpleOptions
- {
- public string? Name { get; set; }
- public int Port { get; set; }
- public bool Enabled { get; set; }
- public double Timeout { get; set; }
- public Guid Id { get; set; }
- }
- [CfgSection]
- public partial class SgNestedOptions
- {
- public string? Name { get; set; }
- public SgDatabaseOptions? Database { get; set; }
- public SgCacheOptions? Cache { get; set; }
- }
- [CfgSection]
- public partial class SgDatabaseOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- public string? Name { get; set; }
- }
- [CfgSection]
- public partial class SgCacheOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- }
- [CfgSection]
- public partial class SgArrayOptions
- {
- public string[]? Tags { get; set; }
- public List<int>? Ports { get; set; }
- }
- [CfgSection]
- public partial class SgDictionaryOptions
- {
- public Dictionary<string, string>? Settings { get; set; }
- }
- [CfgSection]
- public partial class SgComplexOptions
- {
- public string? Name { get; set; }
- public List<SgEndpointOptions>? Endpoints { get; set; }
- public Dictionary<string, string>? Metadata { get; set; }
- }
- [CfgSection]
- public partial class SgEndpointOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- }
- // ========== 反射绑定配置类(用于对比) ==========
- public class ReflectionSimpleOptions
- {
- public string? Name { get; set; }
- public int Port { get; set; }
- public bool Enabled { get; set; }
- public double Timeout { get; set; }
- public Guid Id { get; set; }
- }
- public class ReflectionNestedOptions
- {
- public string? Name { get; set; }
- public ReflectionDatabaseOptions? Database { get; set; }
- public ReflectionCacheOptions? Cache { get; set; }
- }
- public class ReflectionDatabaseOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- public string? Name { get; set; }
- }
- public class ReflectionCacheOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- }
- public class ReflectionArrayOptions
- {
- public string[]? Tags { get; set; }
- public List<int>? Ports { get; set; }
- }
- public class ReflectionDictionaryOptions
- {
- public Dictionary<string, string>? Settings { get; set; }
- }
- public class ReflectionComplexOptions
- {
- public string? Name { get; set; }
- public List<ReflectionEndpointOptions>? Endpoints { get; set; }
- public Dictionary<string, string>? Metadata { get; set; }
- }
- public class ReflectionEndpointOptions
- {
- public string? Host { get; set; }
- public int Port { get; set; }
- }
|