性能基准测试基础:基准测试的定义与目的

说到基准测试,我习惯把它比作「给系统拍一张X光片」。

你想想看,没有这张片子,你怎么知道系统哪里疼?哪里虚?

基准测试(Benchmarking)说白了就是一套标准化的测量流程。它的目的很纯粹:在可控条件下,量化系统的性能表现

核心目的就三个:

  • 建立基线——知道系统「现在」跑得怎么样
  • 发现瓶颈——找到拖后腿的那个环节
  • 验证优化——改完之后,到底有没有变快?

我在项目中遇到过不少团队,上来就调参数、改代码,结果越改越糟。为什么?因为没有基线数据。你都不知道起点在哪,怎么知道终点对不对?

常见的性能指标

搞实时系统,这几个指标你得刻在脑子里。我每次做测试,第一件事就是确认:这次要盯哪个指标?

延迟(Latency)

延迟就是「从发请求到收响应」的时间差。实时系统里,这是命根子。

我习惯把延迟拆成三块看:

  • 最小延迟——理想情况下的表现
  • 平均延迟——日常体验的参考
  • 尾延迟(P99/P999)——最差情况下的底线

嗯,这里要注意:很多新手只看平均延迟,结果线上出问题才发现,P99延迟已经高得离谱了。我曾经吃过这个亏,一个音频处理系统,平均延迟只有5ms,但P99到了200ms——用户听到的就是断断续续的杂音。

吞吐量(Throughput)

吞吐量是「单位时间能处理多少任务」。实时系统里,它和延迟是跷跷板关系。

你想想看,拼命压吞吐量,延迟必然飙升。反过来,死磕低延迟,吞吐量就上不去。怎么平衡?这就是调优的艺术了。

我的经验:做基准测试时,先固定一个指标,再调另一个。比如先设定延迟上限为10ms,然后看最大吞吐量能到多少。这样出来的数据才有实际意义。

抖动(Jitter)

抖动就是延迟的「波动程度」。实时系统里,稳定的低延迟比偶尔的超低延迟更重要。

举个例子:一个系统平均延迟10ms,但有时候跳到100ms,有时候又降到1ms。另一个系统稳定在15ms,从不波动。做音频流处理,我肯定选后者。为什么?因为人耳对抖动极其敏感,稳定的延迟可以通过缓冲区平滑处理,抖动却会直接导致卡顿。

CPU利用率

这个指标大家都懂,但我要提醒一点:别只看平均值

我见过一个案例,CPU平均利用率才40%,但系统就是卡。后来一查,原来是某个核跑满了,其他核在闲着。所以,我习惯看每个核的利用率,以及上下文切换频率。这两个数据比平均值有用得多。

指标 关注点 常见陷阱
延迟 尾延迟(P99) 只看平均值
吞吐量 与延迟的平衡 盲目压榨
抖动 稳定性 忽略波动
CPU利用率 单核负载 只看整体

测试方法论

指标选好了,怎么测?这里有两个原则,我每次做测试都会默念一遍。

控制变量法

说白了就是:一次只改一个东西。

很多同学做测试,上来就改内核参数、调线程优先级、换内存分配器……结果系统变快了,但不知道是哪个改动起了作用。这就像你同时吃了三颗药,肚子不疼了,但不知道是哪颗治好的。

我曾经犯过的错:有一次优化网络栈,同时改了中断亲和性、NAPI参数和套接字缓冲区大小。性能提升了30%,但后来回退测试发现,真正起作用的只有中断亲和性。另外两个改动不仅没用,还增加了内存开销。从那以后,我坚持「改一个、测一次、记一笔」。

具体做法:

  1. 先跑一次基线测试,记录所有指标
  2. 只修改一个参数
  3. 重新测试,对比数据
  4. 确认效果后,再改下一个

重复性测试

一次测试结果不能信。为什么?因为系统有噪声。

你想想看,后台的定时任务、网络波动、甚至温度变化,都会影响测试结果。我习惯每个场景至少跑5次,取中位数或者P50值。如果某次结果明显偏离,我会检查日志,看当时有没有异常事件。

我的小技巧:用脚本自动化重复测试。手动跑5次太累了,而且容易出错。写个简单的Shell脚本,循环执行测试程序,自动收集结果。这样既省力,又能保证每次的测试环境一致。

重复测试还能帮你发现一个隐藏问题:系统是否稳定。如果5次结果差异很大,说明系统本身就不靠谱。这时候别急着调优,先排查稳定性问题。

# 一个简单的重复测试脚本示例
for i in {1..5}
do
    echo "Run #$i"
    ./benchmark --config test.conf --output result_$i.csv
    sleep 2  # 让系统冷却一下
done

嗯,这里要注意:两次测试之间最好留一点间隔。尤其是CPU密集型的测试,跑完一次后CPU温度可能还没降下来,紧接着跑第二次,结果会受热降频影响。我一般等2-3秒,让系统缓一缓。

最后说一句:基准测试不是一次性工作。系统在变,负载在变,基线数据也要定期更新。我每两周会跑一次全量测试,把结果存档。这样哪天系统出问题了,翻出历史数据一对比,问题出在哪一目了然。