HTTP Handler 微基准
运行:
dotnet run -c Release --project benchmarks/MS.Microservice.Core.HttpLogging.Benchmarks/MS.Microservice.Core.HttpLogging.Benchmarks.csproj
每次调用创建 512 B 或 16 KiB 的内存正文,请求经过 LoggingHttpClientHandler,下一层处理器把请求内容复制到 Stream.Null 并返回内存响应,调用方随后也复制响应内容。正文日志场景使用会实际格式化消息的 logger,确保正文读取与格式化计入结果。脱敏场景使用 EnableRedaction=true。
每场景先预热,然后执行 5 轮。报告每次耗时和进程总分配量的中位数。分配值包含请求、响应、内容对象及日志格式化;进程总分配量也可能受到后台活动影响。这里没有网络、磁盘或真实日志提供器,结果不能代表端到端吞吐。
修改前基线
2026-09-23 在 master 提交 31475da 上运行,Windows 10(win-x64)、.NET SDK 10.0.401,Release 配置。每项数据是 5 轮中位数;每轮 512 B 场景执行 5,000 次,16 KiB 场景执行 1,000 次。机器在普通桌面负载下运行,未锁定 CPU 频率。
| 场景 | 耗时 | 分配 |
|---|---|---|
| Information 关闭,请求与响应各 512 B | 4,379.9 ns/次 | 4,144.1 B/次 |
| 完整正文日志,请求与响应各 512 B | 9,759.7 ns/次 | 9,136.1 B/次 |
| 完整正文日志,请求与响应各 16 KiB | 37,724.4 ns/次 | 199,600.7 B/次 |
| 开启脱敏,请求与响应各 512 B | 3,517.1 ns/次 | 1,096.1 B/次 |
这组数据包含基准自身每次构造请求、响应和内存流的成本,只适合同一项目、相同条件下的修改前后比较。正文日志场景的 logger 确实格式化消息,程序会在预热前检查正文是否出现在格式化结果中。
修改后复测
采用异步正文读取并保留 EnableRedaction 后,使用同一个 Release 基准项目复测 3 次。下表中的修改后耗时是这 3 次运行各自报告的中位数范围;修改后分配量是 3 次运行中稳定的近似值。修改前列沿用上面的单次基线运行。
| 场景 | 修改前耗时 | 修改后耗时范围 | 修改前分配 | 修改后分配 |
|---|---|---|---|---|
| Information 关闭,请求与响应各 512 B | 4,379.9 ns/次 | 1,255–2,811 ns/次 | 4,144.1 B/次 | 约 616 B/次 |
| 完整正文日志,请求与响应各 512 B | 9,759.7 ns/次 | 10,014–14,928 ns/次 | 9,136.1 B/次 | 约 7,392 B/次 |
| 完整正文日志,请求与响应各 16 KiB | 37,724.4 ns/次 | 46,030–74,773 ns/次 | 199,600.7 B/次 | 约 166,112 B/次 |
| 开启脱敏,请求与响应各 512 B | 3,517.1 ns/次 | 4,315–8,898 ns/次 | 1,096.1 B/次 | 约 1,096 B/次 |
在这个基准中,Information 关闭时每次分配约减少 3,528 B;完整正文日志的 512 B 与 16 KiB 场景分别约减少 1,744 B 和 33,489 B;脱敏场景分配基本不变。三次运行的耗时波动较大,不能据此断言延迟改善。处理器只在进程内复制内存正文,没有真实 HTTP 连接、网络 I/O 或真实日志后端;进程总分配量还可能包含其他线程的活动,因此这些数字不代表实际服务吞吐。