hyperfine 使用指南
简介
测量程序运行耗时是一个常见的需求。
我们经常会调整自己编写的程序,来给程序加速。但是自己提出的加速计划,不一定会被
机器认可。比如,你觉得 ++i
比 i++
更快并且花了两天时间把程序里所有的后缀全
改成了前缀,但是机器不管,她编译的时候直接把你的写法给扬掉了。这个时候再在 git
的提交信息里写 perf: 优化 XX 部分性能
就会显得非常滑稽。所以,我们经常需要对
程序性能测试来保证自己的优化是有效的。对程序性能测试的最常用的方法就是计时。
小时候幼儿园的老师经常教育我们,在 bash 里面用 time
的命令就可以测量程序
运行的时间。这也是大家最常用的方法。但是我们都知道,time
是一个非常粗糙的工
具。用它测量程序性能时,总会遇到这么几个问题:
- 测量出来的时间真的是准的吗?会不会受到系统波动的影响?
- 测量出来的时间有多可靠?该怎么知道测量误差?
- 我能比较轻松地对比两个或多个程序的性能吗?
我们可以通过写一堆土制脚本来解决上述问题,但是与其费心写功能不全、漏洞百出的脚
本,还不如直接使用已有的趁手工具。
hyperfine 就是一个优秀的性能测试工具。
优势
根据 hyperfine 自己的 介绍 ,hyperfine 拥有如下功能:
- 多次测量并统计均值方差
- 支持任意 shell 命令
- 进度条和预估剩余时间
- 预热:正式测试之前先运行几次
- 测试之前执行指定命令(可用于清除缓存)
- 自动发现 cache 影响和系统性能波动影响
- 多种输出格式,支持 CSV、JSON、Markdown 等等
- 跨平台
(注:hyperfine 的介绍是有 中文翻译 的,但是我看的时候它略微有些过时了。
希望有好心人来更新一下翻译)
它的使用截图如下:
个人评测:life-changing 的好东西,我现在没有 hyperfine 都不会测程序了。
基本使用
hyperfine 的使用方式非常符合直觉,命令行结构和选项设计得很好。
安装
hyperfine 是用 rust 写的(不打算去学一下?)。如果机器上有 rust 开发环境,
直接运行 cargo install hyperfine
即可完成安装。cargo 是 rust 的编译系统
和依赖管理工具。
如果机器上没有 rust 开发环境,可以求助你的包管理器,或者从
hyperfine 在 Github 上的发布页面 中,下载与自己的机器架构对应的二进制
文件。
测试单个程序
命令:
hyperfine 'hexdump file'
结果:
11:17 jyi-station ~/tmp/bgifile
0 hyperfine 'hexdump test13.c'
Benchmark 1: hexdump test13.c
Time (mean ± σ): 385.0 ms ± 5.1 ms [User: 383.0 ms, System: 2.1 ms]
Range (min … max): 381.6 ms … 398.9 ms 10 runs
从结果可以看出,hyperfine 把程序运行了 10 次。测量出来平均耗时是 385 ms,误差
是 5.1 ms。运行的时候,hyperfine 把程序的所有输出重定向到了 /dev/null
里,所
以终端上没有多余的内容。
你看,我几乎什么都没做,只是把命令提供给 hyperfine,她就自动帮忙把所有东西都测
好了!
我们甚至无需检查误差是否过大,因为 hyperfine 会自动检测误差过大的情况,并且根
据程序运行时间的特征来猜测可能发生了什么问题,并给出一些建议。非常贴心。后面会
详细讨论这些细节。
对比测试多个程序
命令:
hyperfine 'hexdump test13.c' 'xxd test13.c' 'xxd test14.c'
结果:
11:24 jyi-station ~/tmp/bgifile
0 hyperfine 'hexdump test13.c' 'xxd test13.c' 'xxd test14.c'
Benchmark 1: hexdump test13.c
Time (mean ± σ): 383.6 ms ± 1.9 ms [User: 381.8 ms, System: 1.6 ms]
Range (min … max): 381.6 ms … 387.7 ms 10 runs
Benchmark 2: xxd test13.c
Time (mean ± σ): 90.2 ms ± 1.0 ms [User: 88.4 ms, System: 1.9 ms]
Range (min … max): 88.7 ms … 93.4 ms 32 runs
Benchmark 3: xxd test14.c
Time (mean ± σ): 180.2 ms ± 2.8 ms [User: 176.8 ms, System: 3.2 ms]
Range (min … max): 177.1 ms … 186.6 ms 16 runs
Summary
'xxd test13.c' ran
2.00 ± 0.04 times faster than 'xxd test14.c'
4.25 ± 0.05 times faster than 'hexdump test13.c'
在这个例子里,我们给了 hyperfine 三个参数,让她测量三个程序的耗时。hyperfine
首先输出了三个程序各自的运行结果,这部分和测试单个程序时的结果差不多。但是在报
告的最后,hyperfine 还额外给出了一些信息。她指出了跑的最快的程序(港记程序