如何在BenchmarkDotNet中测量基准测试进程的CPU使用率
BenchmarkDotNet CPU使用率采集方案
功能支持性说明
BenchmarkDotNet 原生默认不直接输出测试进程的CPU使用率百分比数据,你当前拿到的输出表格中Mean/Error/StdDev属于被测方法的CPU耗时统计,并非使用率维度的数值。
实现CPU使用率采集的两种方案
方案1:自定义诊断器扩展(推荐)
通过实现BenchmarkDotNet的自定义诊断器,可以把CPU使用率指标直接集成到你现有的结果表格中,和内存、耗时指标同步输出:
- 继承
IDiagnoser接口,在测试启动、结束的生命周期钩子中分别记录CPU时间与墙上时间 - 计算逻辑需适配多核CPU,避免出现使用率超过100%的不符合预期的结果
- 最终将计算出的使用率注册为自定义输出列即可
核心实现代码参考:
using System.Diagnostics; using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Engines; public class CpuUsageDiagnoser : IDiagnoser { private Process _targetProcess; private TimeSpan _startCpuTime; private DateTime _startWallTime; public void OnBenchmarkStart(BenchmarkCase benchmarkCase) { _targetProcess = Process.GetCurrentProcess(); _startCpuTime = _targetProcess.TotalProcessorTime; _startWallTime = DateTime.UtcNow; } public void OnBenchmarkEnd(BenchmarkCase benchmarkCase) { var endCpuTime = _targetProcess.TotalProcessorTime; var endWallTime = DateTime.UtcNow; var cpuUsedMs = (endCpuTime - _startCpuTime).TotalMilliseconds; var totalWallMs = (endWallTime - _startWallTime).TotalMilliseconds; // 多核CPU下使用率计算逻辑 var cpuUsagePercentage = cpuUsedMs / (Environment.ProcessorCount * totalWallMs) * 100; // 此处将cpuUsagePercentage注册为自定义输出列即可 } // 其余接口方法可按需求实现空逻辑 public void Handle(HostSignal signal, DiagnoserActionParameters parameters) {} public IEnumerable<Metric> ProcessResults(DiagnoserResults results) => Enumerable.Empty<Metric>(); }
在测试类上添加特性即可启用该诊断器:[SimpleJob, Diagnoser(typeof(CpuUsageDiagnoser))]
方案2:外部工具独立采集
如果不想修改基准测试代码,可以直接用系统/ dotnet 官方工具独立采集:
- Windows环境:使用性能监视器(PerfMon)添加对应测试进程的CPU使用率计数,或者在任务管理器详细信息页固定监控测试进程
- Linux环境:使用
top、pidstat命令过滤测试进程PID,按自定义间隔输出CPU使用率 - 跨平台通用:使用dotnet官方诊断工具
dotnet-counters,执行命令dotnet counters monitor --process-id <测试进程PID> System.Runtime[cpu-usage]即可实时输出进程CPU使用率
内容的提问来源于stack exchange,提问作者egvrcn
相关产品推荐
相关产品推荐

