本目录包含 Apq.Cfg 配置库的性能基准测试,使用 BenchmarkDotNet 框架。
仓库地址:https://gitee.com/apq/Apq.Cfg
benchmarks/
└── Apq.Cfg.Benchmarks/ # 多目标框架基准测试项目
├── Apq.Cfg.Benchmarks.csproj # 支持 net6.0;net8.0;net9.0
├── Program.cs # 入口程序
│
├── # 基础性能测试
├── ReadWriteBenchmarks.cs # 读写性能测试
├── LargeFileBenchmarks.cs # 大文件加载测试
├── ConcurrencyBenchmarks.cs # 并发访问测试
│
├── # 操作性能测试
├── SaveBenchmarks.cs # 持久化性能测试
├── RemoveBenchmarks.cs # 删除操作测试
├── BatchOperationBenchmarks.cs # 批量操作测试(GetMany/SetMany)
│
├── # 高级场景测试
├── MultiSourceBenchmarks.cs # 多源合并测试
├── KeyPathBenchmarks.cs # 键路径深度测试
├── TypeConversionBenchmarks.cs # 类型转换测试(含扩展方法)
├── CacheBenchmarks.cs # 缓存效果测试
├── GetSectionBenchmarks.cs # 配置节访问测试
├── MicrosoftConfigBenchmarks.cs # Microsoft Configuration 转换测试
│
├── # 新增功能测试
├── EncodingBenchmarks.cs # 编码检测性能测试
├── ObjectBinderBenchmarks.cs # 对象绑定性能测试(反射)
├── SourceGeneratorBenchmarks.cs # 源生成器绑定性能测试(零反射)
├── DependencyInjectionBenchmarks.cs # 依赖注入集成性能测试
│
├── # 远程配置中心测试
├── ConsulBenchmarks.cs # Consul 配置中心性能测试
└── EtcdBenchmarks.cs # Etcd 配置中心性能测试
说明:以下所有命令均在项目根目录执行。
# 运行所有基准测试(Release 模式必须)
# 使用 .NET 9 作为宿主运行,自动测试 .NET 6/8/9 三个版本
# 结果自动保存到带时间戳的子目录
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --filter *
# 运行特定测试类
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --filter *ReadWriteBenchmarks*
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --filter *CacheBenchmarks*
# 运行特定测试方法
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --filter *Json_Get*
# 组合多个过滤器
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --filter *Json* --filter *Ini*
注意:
--是必须的,它将后面的参数传递给 BenchmarkDotNet 而不是 dotnet 命令。
# 列出所有可用测试(不实际运行)
dotnet run -c Release --project benchmarks/Apq.Cfg.Benchmarks -f net9.0 -- --list flat
说明:导出格式(Markdown、HTML、CSV)已在
BenchmarkConfig中配置,无需手动指定。
测试不同配置源(JSON/INI/XML/YAML/TOML)的基本操作性能:
| 测试方法 | 说明 |
|---|---|
| Json/Ini/Xml/Yaml/Toml_Get | 读取字符串值 |
| Json/Ini/Xml/Yaml/Toml_GetInt | 读取并转换类型(如 int) |
| Json/Ini/Xml/Yaml/Toml_Exists | 检查键是否存在 |
| Json/Ini/Xml/Yaml/Toml_Set | 写入配置值 |
测试加载大量配置项时的性能,参数化测试项数量:
| 参数 | 说明 |
|---|---|
| 100 项 | 小型配置 |
| 1000 项 | 中型配置 |
| 5000 项 | 大型配置 |
| 测试方法 | 说明 |
|---|---|
| Json/Ini/Xml/Yaml/Toml_Load | 纯加载性能 |
| Json/Ini/Xml/Yaml/Toml_LoadAndRead | 加载后读取特定键 |
测试多线程环境下的性能,支持多种配置源和线程数量参数化:
| 参数 | 说明 |
|---|---|
| ThreadCount: 1/4/8 | 线程数量 |
| SourceType: Json/Ini | 配置源类型(选取最快和最常用的两种) |
| 测试方法 | 说明 |
|---|---|
| ConcurrentRead_SameKey | 多线程读取同一键 |
| ConcurrentRead_DifferentKeys | 多线程读取不同键 |
| ConcurrentWrite_DifferentKeys | 多线程写入不同键 |
| ConcurrentWrite_SameKey | 多线程写入同一键(竞争场景) |
| ConcurrentMixed_ReadWrite | 混合读写操作 |
| ConcurrentExists | 并发检查键存在 |
测试 SaveAsync 在不同数据量下的性能:
| 参数 | 说明 |
|---|---|
| ChangeCount: 10/100 | 变更数量 |
| 测试方法 | 说明 |
|---|---|
| Json/Ini/Xml/Yaml/Toml_Save | 批量写入后保存 |
| Json/Ini_SaveLargeValue | 大值保存测试 |
| Json/Ini_FrequentSave | 频繁保存测试 |
测试 Remove 操作在不同场景下的性能:
| 参数 | 说明 |
|---|---|
| KeyCount: 10/50 | 键数量 |
| 测试方法 | 说明 |
|---|---|
| *_RemoveSingle | 单键删除 |
| *_RemoveBatch | 批量删除 |
| *_RemoveNonExistent | 删除不存在的键 |
| *_RemoveAndSave | 删除后保存 |
测试多个配置源叠加时的查询性能:
| 参数 | 说明 |
|---|---|
| SourceCount: 1/3/5 | 配置源数量 |
| 测试方法 | 说明 |
|---|---|
| Read_HighPriorityKey | 读取高优先级源的键 |
| Read_LowPriorityKey | 读取低优先级源的键 |
| Read_SharedKey | 读取被覆盖的共享键 |
| Read_MultipleKeys | 批量读取多个键 |
| Exists_* | 存在性检查 |
| Write_* | 写入测试 |
| Get_Int* | 类型转换测试 |
测试不同深度的键路径解析性能:
| 参数 | 说明 |
|---|---|
| PathDepth: 1/5/10 | 路径深度 |
| 测试方法 | 说明 |
|---|---|
| Get_DeepKey | 读取深层嵌套的键 |
| Get_DeepKey_Multiple | 批量读取深层键 |
| Get_DeepKey_Int/Bool | 深层键类型转换 |
| Exists_DeepKey | 深层键存在性检查 |
| Set_DeepKey | 写入深层键 |
| Get_ShallowKey | 浅层键对比基准 |
测试 Get 不同类型转换的性能开销:
| 测试类别 | 测试方法 |
|---|---|
| BasicTypes | Get_String, Get_Int, Get_Long, Get_Double, Get_Decimal, Get_Bool |
| ComplexTypes | Get_Guid, Get_DateTime, Get_Enum, Get_NullableInt |
| Batch | Get_*_Multiple(批量转换) |
| SpecialValues | Get_LongString, Get_Unicode, Get_SpecialChars, Get_EmptyString |
| Extensions | TryGet_Success/Failure, GetRequired_Success, GetOrDefault_ExistingKey/NonExistingKey |
| Mixed | Get_MixedTypes(混合类型读取) |
测试热路径重复读取、缓存命中/未命中等场景:
| 测试类别 | 测试方法 |
|---|---|
| HotPath | HotPath_SameKey_1000/10000, HotPath_TwoKeys_Alternating, HotPath_FewKeys_Loop |
| CacheMiss | CacheMiss_NonExistentKey_1000, CacheMiss_DifferentNonExistentKeys, CacheMiss_MixedExistence |
| ColdPath | ColdPath_Sequential_100Keys, ColdPath_Random_Pattern |
| ExistsCache | Exists_SameKey_1000, Exists_NonExistentKey_1000, Exists_Mixed_1000 |
| WriteInvalidation | WriteAndRead_SameKey, WriteAndRead_DifferentKeys, BatchWrite_ThenBatchRead |
| FirstAccess | FirstAccess_NewKey, SubsequentAccess_Warmed |
测试 GetSection 和 GetChildKeys 操作的性能:
| 测试类别 | 测试方法 |
|---|---|
| GetSection | Json/Ini/Xml/Yaml/Toml_GetSection(基本配置节获取) |
| GetSectionNested | Json/Ini/Xml/Yaml/Toml_GetSection_Nested(嵌套配置节获取) |
| GetSectionThenGet | Json/Ini/Xml/Yaml/Toml_GetSection_ThenGet(配置节 + 读取组合) |
| GetChildKeys | Json/Ini/Xml/Yaml/Toml_GetChildKeys(根级子键枚举) |
| SectionGetChildKeys | Json/Ini/Xml/Yaml/Toml_Section_GetChildKeys(配置节子键枚举) |
| DirectVsSection | Json_DirectGet vs Json_SectionGet(直接访问 vs 配置节访问对比) |
测试 GetMany/SetMany 批量操作与单次循环操作的性能对比:
| 测试类别 | 测试方法 |
|---|---|
| GetMany | GetMany_10Keys/50Keys/100Keys vs Get_Loop_10Keys/50Keys/100Keys |
| GetManyTyped | GetMany_Typed_10Keys vs Get_Typed_Loop_10Keys |
| SetMany | SetMany_10Keys/50Keys/100Keys vs Set_Loop_10Keys/50Keys/100Keys |
| Mixed | BatchRead_ThenBatchWrite vs LoopRead_ThenLoopWrite |
测试 ToMicrosoftConfiguration 和 ConfigChanges 的性能:
| 测试类别 | 测试方法 |
|---|---|
| ToMsConfig | ToMicrosoftConfiguration_Static/Dynamic/Multiple |
| ReadComparison | Read_ViaApqCfg vs Read_ViaMsConfig, BatchRead_ViaApqCfg vs BatchRead_ViaMsConfig |
| ConfigChanges | Subscribe_ConfigChanges, Subscribe_AndTriggerChange, MultipleSubscribers |
测试编码检测和映射的性能:
| 测试类别 | 测试方法 |
|---|---|
| BOM 检测 | Detect_UTF8_WithBOM, Detect_UTF16LE_WithBOM |
| 无 BOM 检测 | Detect_UTF8_NoBOM, Detect_GB2312 |
| 缓存效果 | Detect_Cached_1000, Detect_Uncached_100 |
| 大文件 | Detect_LargeFile |
| 编码映射 | Mapping_ExactPath_Lookup, Mapping_Wildcard_Lookup |
| 混合场景 | Detect_MixedEncodings_10 |
测试 ObjectBinder(基于反射)绑定不同类型对象的性能:
| 测试类别 | 测试方法 |
|---|---|
| 简单类型 | Bind_SimpleTypes, Bind_SimpleTypes_100 |
| 嵌套对象 | Bind_NestedObject, Bind_NestedObject_100 |
| 数组/列表 | Bind_Array, Bind_Array_100 |
| 字典 | Bind_Dictionary, Bind_Dictionary_100 |
| 复杂对象 | Bind_ComplexObject, Bind_ComplexObject_100 |
对比源生成器(编译时生成代码,零反射)与 ObjectBinder(运行时反射)的性能差异:
| 测试类别 | 测试方法 |
|---|---|
| 简单类型 | SourceGen_SimpleTypes vs Reflection_SimpleTypes |
| 简单类型批量 | SourceGen_SimpleTypes_100 vs Reflection_SimpleTypes_100 |
| 嵌套对象 | SourceGen_NestedObject vs Reflection_NestedObject |
| 嵌套对象批量 | SourceGen_NestedObject_100 vs Reflection_NestedObject_100 |
| 数组/列表 | SourceGen_Array vs Reflection_Array |
| 数组/列表批量 | SourceGen_Array_100 vs Reflection_Array_100 |
| 字典 | SourceGen_Dictionary vs Reflection_Dictionary |
| 字典批量 | SourceGen_Dictionary_100 vs Reflection_Dictionary_100 |
| 复杂对象 | SourceGen_ComplexObject vs Reflection_ComplexObject |
| 复杂对象批量 | SourceGen_ComplexObject_100 vs Reflection_ComplexObject_100 |
| BindTo | SourceGen_BindTo vs Reflection_BindTo |
预期结果:源生成器绑定应比反射绑定快 2-5 倍,且内存分配更少。
测试 DI 集成的注册和解析性能:
| 测试类别 | 测试方法 |
|---|---|
| 注册 | AddApqCfg_Register, AddApqCfg_WithOptions_Register |
| ConfigureApqCfg | ConfigureApqCfg_Single, ConfigureApqCfg_Multiple |
| IOptions | Resolve_IOptions, Resolve_IOptions_100 |
| IOptionsMonitor | Resolve_IOptionsMonitor, Resolve_IOptionsMonitor_100 |
| IOptionsSnapshot | Resolve_IOptionsSnapshot, Resolve_IOptionsSnapshot_100 |
| ICfgRoot | Resolve_ICfgRoot, Resolve_ICfgRoot_ThenGet |
| 复杂对象 | Resolve_ComplexOptions, Resolve_MultipleOptions |
测试 Consul 配置源的读写性能:
| 测试类别 | 测试方法 |
|---|---|
| 基本读写 | Consul_Get, Consul_Set, Consul_Exists, Consul_Remove |
| 批量操作 | Consul_Get_Multiple, Consul_Set_Multiple |
| 热重载 | Consul_Watch_ChangeDetection |
注意:需要运行 Consul 服务才能执行此测试。
测试 Etcd 配置源的读写性能:
| 测试类别 | 测试方法 |
|---|---|
| 基本读写 | Etcd_Get, Etcd_Set, Etcd_Exists, Etcd_Remove |
| 批量操作 | Etcd_Get_Multiple, Etcd_Set_Multiple |
| 热重载 | Etcd_Watch_ChangeDetection |
注意:需要运行 Etcd 服务才能执行此测试。
本项目使用自定义 BenchmarkConfig 配置,自动对比 .NET 6/8/9 三个版本的性能。
运行完成后,结果保存在带时间戳的子目录中,便于追踪历史性能变化:
benchmarks/Apq.Cfg.Benchmarks/
└── BenchmarkDotNet.Artifacts/
├── 2024-12-24_143052/ # 按时间戳保留
│ └── results/
│ ├── *-report.csv # CSV 格式数据
│ ├── *-report.html # HTML 可视化报告
│ └── *-report-github.md # GitHub Markdown 格式
├── 2024-12-25_091530/ # 另一次测试
│ └── results/
└── ...
| 列名 | 说明 |
|---|---|
| Mean | 平均执行时间 |
| Error | 误差范围 |
| StdDev | 标准差 |
| Median | 中位数 |
| Rank | 性能排名 |
| Gen0/Gen1/Gen2 | GC 代数统计 |
| Allocated | 内存分配量 |
| 测试类 | Get | Set | Exists | Remove | Save | Load | 并发 | 类型转换 | GetSection | GetMany | SetMany | ToMsConfig | ConfigChanges | 编码检测 | 对象绑定 | 源生成器 | DI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ReadWriteBenchmarks | ✅ | ✅ | ✅ | - | - | - | - | ✅ | - | - | - | - | - | - | - | - | - |
| LargeFileBenchmarks | ✅ | - | - | - | - | ✅ | - | - | - | - | - | - | - | - | - | - | - |
| ConcurrencyBenchmarks | ✅ | ✅ | ✅ | - | - | - | ✅ | - | - | - | - | - | - | - | - | - | - |
| SaveBenchmarks | - | ✅ | - | - | ✅ | - | - | - | - | - | - | - | - | - | - | - | - |
| RemoveBenchmarks | - | - | - | ✅ | ✅ | - | - | - | - | - | - | - | - | - | - | - | - |
| MultiSourceBenchmarks | ✅ | ✅ | ✅ | - | - | - | - | ✅ | - | - | - | - | - | - | - | - | - |
| KeyPathBenchmarks | ✅ | ✅ | ✅ | - | - | - | - | ✅ | - | - | - | - | - | - | - | - | - |
| TypeConversionBenchmarks | ✅ | - | - | - | - | - | - | ✅ | - | - | - | - | - | - | - | - | - |
| CacheBenchmarks | ✅ | ✅ | ✅ | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
| GetSectionBenchmarks | ✅ | - | - | - | - | - | - | - | ✅ | - | - | - | - | - | - | - | - |
| BatchOperationBenchmarks | ✅ | ✅ | - | - | - | - | - | ✅ | - | ✅ | ✅ | - | - | - | - | - | - |
| MicrosoftConfigBenchmarks | ✅ | ✅ | - | - | - | - | - | - | - | - | - | ✅ | ✅ | - | - | - | - |
| EncodingBenchmarks | - | - | - | - | - | - | - | - | - | - | - | - | - | ✅ | - | - | - |
| ObjectBinderBenchmarks | - | - | - | - | - | - | - | - | - | - | - | - | - | - | ✅ | - | - |
| SourceGeneratorBenchmarks | - | - | - | - | - | - | - | - | - | - | - | - | - | - | ✅ | ✅ | - |
| DependencyInjectionBenchmarks | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | ✅ |
| ConsulBenchmarks | ✅ | ✅ | ✅ | ✅ | - | - | - | - | - | - | - | - | ✅ | - | - | - | - |
| EtcdBenchmarks | ✅ | ✅ | ✅ | ✅ | - | - | - | - | - | - | - | - | ✅ | - | - | - | - |
-f net9.0 等参数--runtimes 参数可在一次运行中对比多个版本--filter 缩小范围详细性能测试结果见 BENCHMARK_RESULTS.md