benchmark-checklist
基准测试检查清单
Section titled “基准测试检查清单”每当你要给出一个性能数字,就用这份清单。比如 PR 的前后对比、某处退步的结论、hillclimb 用的 harness(负责运行和测量的程序),或者库和配置的选型。解释这个数字 讲了为什么要这样做。下面每个问题都要拿一次运行里的证据来回答,不能凭对代码的猜测。
如果用户要的只是一个快速的粗略估计,跑一次就够。但第 4 问和第 7 问仍然要查,并且要说明只跑了一次。其余问题可以跳过,除非这次运行看起来不对。在几个选项之间做选择,从来不算粗略估计。
- 先写下你预计要给出的结论,用你最终会发出去的原话,例如「在 6 万行的数据集上,导出的 p50 快了 30%」。后面的问题检验的就是这句话。
- 读一遍测量脚本。记下它给什么计时、统计了什么、忽略了什么。
- 用
uptime看平均负载,用nproc看核心数。机器很忙的话,查清楚在跑什么。如果停不掉,就让对比的两边交替运行,让两边受到同样的噪声干扰,并在报告里写明这一点。
- 为什么不是两倍? 说出限制因素。剖析要放在一次不拿来汇报的运行里做,因为剖析器和追踪器会拖慢工作。可用的手段有:每个进程的 CPU 占用(
top、pidstat)、对应运行时的剖析器(node --cpu-prof、py-spy、perf)、I/O 等待,以及系统调用次数(Linux 上的strace -c)。然后把热点对应到源码。施压程序也要盯着。如果它先跑满,你测到的就是施压程序。如果一个改动没有让数字变化,限制因素能解释原因。所以在断定这个改动没用之前,先把限制因素找出来。 - 调优了吗? 每一边都要按生产环境的方式运行:发布构建,生产环境用的参数和环境变量,批处理和事务设置,连接池,冷热程度和生产环境一致的缓存,以及相同的版本和数据。如果有一边用的是默认设置,你比较的就是两套配置,而不是两种实现。如果限制因素是一项设置,比如每行提交一次、调试构建、缺了一个索引,就说明那一边没调优。先调优,再测一次,然后才能选出胜者。调不了,就不要凭这次运行选胜者。用户在决定采用哪个方案时,把结论收窄成「只针对今天发布的代码」也补救不了,因为用户采用的是这个方案,不是今天这套设置。
- 超出极限了吗? 算一算。拿每秒字节数去比磁盘和网络带宽。拿每秒操作数乘以每次操作的开销,去比你手上的核心数。拿省下的时间,去比改动的那部分原本花的时间。去掉一个占整次运行 10% 的部分,整次运行最多只能快大约 11%。结果超过了极限,就说明这次运行测到的不是这项工作,而是别的东西,比如缓存、空操作或 bug。
- 出错了吗? 统计失败次数和非成功的响应,还要检查输出是对的,不能只看有没有输出。出错和成功的表现不一样。拒绝往往很快,超时和重试则很慢。如果脚本不统计错误,就把计数加上。
- 能复现吗? 每一边至少跑 5 次,并且两边交替运行(A、B、A、B,依此类推),这样预热、延迟初始化、缓存和漂移都不会偏向某一边。报告中位数和范围。差距比各次运行之间的波动还小,就算作没有可测出的差别。结果难分高下时,用秩和检验,或者 harness 自带的统计。
- 这重要吗? 任何局部结果旁边,都要同时测量用户实际在等的那条端到端路径,并使用贴近真实的数据量和并发。把局部结果写成它在整体中的占比。一个只占请求 1% 的辅助函数,不管自己变得多快,整个请求最多也只能快 1%。
- 工作真的发生了吗? 确认工作在计时区间内真的运行了:请求到达了服务器,行写进去了,字节读出来了,代码用上了结果。惰性代码(没人迭代的生成器、没人等待的 promise、JIT 可以丢弃的结果)和超时,都会给根本没发生的工作产出数字。
- 开头先给 verdict(结论):更快、更慢、没有可测出的差别,或无法下结论。
- 给出数字时,带上单位、运行次数、范围和限制因素。例如「p50 从 41 ms 降到 33 ms,每边 7 次运行的中位数,改动后范围 32 到 35 ms,受限于单核上的 JSON 解析」。
- 出现下面任一情况,verdict 就写无法下结论:你声称有差别,却说不出限制因素;有一边没调优;你没能检查第 4 问和第 7 问。写明缺口在哪里。
- 按 Opening a PR playbook,PR 正文只放一个主要数字。各次运行、范围和限制因素的证据,放进一份链接过去的产物或笔记文件里。
和其他性能资料的分工
Section titled “和其他性能资料的分工”- Perf issue playbook 负责找出并修好慢的地方,修法由它的几类策略产生。这个 skill 先核查它的基线,那份 playbook 才依据基线做计划。之后的每个数字,也由这个 skill 核查。
- Hillclimb playbook 围绕一个指标反复循环。这个 skill 在它的 harness 冻结之前先核查 harness。冻结之后,harness 会打印出错次数和工作量计数,所以每次决定保留还是回退时,第 4 问和第 7 问都顺带查过了。
