上一篇写完 bat 之后预告过,这次实测 sharkdp/hyperfine(读星数约 2.9 万,2026-11-06)。
前面几篇测 ripgrep、fd、bat,我都在手写「预热 + TIMEFORMAT 循环 + 自己数中位数」。能用,但麻烦:没有标准差、没有相对倍数、没有一键导出 Markdown/JSON,异常值要靠眼睛挑。hyperfine 就是同一作者做的命令行基准工具------宣传自己能自动预热、统计、对比和导出。2026-10 刚发了 2.0.0 ,默认行为还变了(命令默认不 走 shell)。我装上之后,先用它复测了上一篇 bat 那组数字,再把 warmup、--runs、导出、-L / -P 参数化都跑通。
本机实测 + AI 辅助整理。测量时间:2026-11-06(Asia/Shanghai)。除特别说明外,hyperfine 2.0.0 终端默认报 均值 ± σ ;文内关键对比同时给出 JSON 里的 中位数(schema version 2),方便和上一篇 bat 手写中位数对齐。hyperfine 默认吞掉被测命令的 stdout/stderr,等价于「输出不影响终端刷新」的测法。
本机环境
text
OS: Debian 13 x86_64,8 核
hyperfine: 2.0.0(GitHub release 二进制)
bat: 0.26.1(上一篇同款)
cat: GNU coreutils 9.7
安装又踩了和 bat / fd 一样的 apt 坑:
text
$ sudo apt-get install -y hyperfine
E: Unable to locate package hyperfine
本机 Debian 源里直接没有包。改走官方 release(与 bat 同一套路):
bash
curl -sL -o hyperfine.tar.gz \
https://github.com/sharkdp/hyperfine/releases/download/v2.0.0/hyperfine-v2.0.0-x86_64-unknown-linux-gnu.tar.gz
tar xzf hyperfine.tar.gz
mkdir -p ~/.local/bin
cp hyperfine-v2.0.0-x86_64-unknown-linux-gnu/hyperfine ~/.local/bin/hyperfine
# 部分发行版可用:sudo apt install hyperfine
# 或 .deb:https://github.com/sharkdp/hyperfine/releases
macOS 一般是 brew install hyperfine。下文统一写 hyperfine。
测试素材
直接复用 bat 那篇的 corpus:
| 文件 | 大小 | 用途 |
|---|---|---|
typing.py(Python 标准库) |
130 KB | 中等源码,看启动开销 |
large_concat.py |
2.96 MB | 上一篇高亮成本的主角之一 |
large_js.js |
6.67 MB | 关颜色吞吐对照 |
为什么不用手写 time 循环?
对 sleep 0.05 各跑 10 次。bash:
bash
for i in $(seq 1 10); do
TIMEFORMAT='%R'; time sleep 0.05
done
本机拿到一串裸秒数:0.051 0.052 0.053 0.051 0.057 0.051 0.053 0.051 0.051 0.054------没有均值、没有 σ、没有「相对谁慢多少」。
同一条命令交给 hyperfine:
bash
hyperfine -w 3 -r 20 'sleep 0.05'
本机结果(JSON 复核):均值 52.4 ms,中位数 52.5 ms,σ ≈ 1.8 ms (预热 3,正式 20 次)。终端还会顺带报峰值内存。这就是换工具的理由:同一组原始时间,直接变成可引用的统计结果。
实测 1:复测 bat------标题里的 2.39s / 3.0ms 从哪来
上一篇用手写循环得出:2.96MB 拼接源码上,cat 约 0.94ms、bat 关颜色约 16ms、开高亮约 2.4s。今天用 hyperfine 在同一台机器、同一份热缓存文件上复测(-w 2 -r 7,输出由 hyperfine 吞掉):
| 命令 | 均值 | 中位数 | 相对 cat(按均值) |
|---|---|---|---|
cat large_concat.py |
2.8 ms | 3.0 ms | 1× |
bat --paging=never --color=never |
17.5 ms | 16.4 ms | ≈6.4× |
bat --paging=never --color=always |
2399 ms | 2393 ms | ≈870× |
结论和上一篇同向:关颜色大约慢一个数量级内;一开高亮就到约 2.39 秒 。绝对数字和手写循环略有出入(今天 cat 中位数约 3.0ms,上次约 0.94ms------短命令本身噪声大,且两次测法、runs 数不同),但「开高亮贵三个数量级」这个故事站得住。hyperfine 额外给出了 σ(开高亮仅 ±19 ms)和相对倍数,不用自己算。
6.67MB JS 关颜色对照(-w 2 -r 10):
| 命令 | 均值 | 中位数 |
|---|---|---|
cat large_js.js |
1.1 ms | 1.07 ms |
bat --paging=never --color=never |
28.1 ms | 28.0 ms |
关颜色大约 26× 。开高亮上一篇已测到 12.4s,今天没再烧时间重跑秒级高亮;需要时把上面第三条命令的文件换成 large_js.js 即可。
130KB typing.py(-w 3 -r 30):
| 命令 | 均值 | 中位数 |
|---|---|---|
cat |
0.50 ms | 0.50 ms |
bat --color=never |
3.75 ms | 3.86 ms |
关颜色大约 7.4×,和上一篇「约 6.8×」同一量级。
可复现:
bash
# 预热文件进页缓存
cat large_concat.py >/dev/null
hyperfine -w 2 -r 7 \
'cat large_concat.py' \
'bat --paging=never --color=never large_concat.py' \
'bat --paging=never --color=always large_concat.py'
实测 2:warmup 与 --runs 到底在干什么
同一条 bat --color=never large_concat.py:
| 设置 | 均值 | 说明 |
|---|---|---|
-r 5(无 warmup) |
25.9 ms | 首几次更容易碰到缓存未热 |
-w 3 -r 5 |
19.7 ms | 先白跑 3 次再计入统计 |
I/O 相关命令建议至少 -w 1;对比短命令可以把 -w 拉到 3~10。
--runs / -r 钉死次数;不写 -r 时 hyperfine 会按稳定性自动加跑------本机对 sleep 0.001 自动跑到了 1046 次。短命令想少花时间,用 -r 或同时设 --max-runs。
实测 3:导出 JSON / Markdown
bash
hyperfine -w 3 -r 20 \
--export-json out.json \
--export-markdown out.md \
'cat typing.py' \
'bat --paging=never --color=never typing.py'
本机 out.md 直接就是表(2.0 导出的是均值,主键指标):
| Command | Mean Wall Time ms | Change | Factor |
|---|---|---|---|
cat .../typing.py |
1.2 ± 1.0 | ||
bat --color=never ... |
5.0 ± 2.0 | +300.4% | (4.0x slower) |
JSON 是 schema version 2 (2.0 破坏性变更):以前的 results[i].mean 变成 results[i].summary.time_wall_clock.mean,中位数在同级的 median。写脚本读导出时别按 1.x 字段硬解。本机从 JSON 抽出的中位数:cat 0.64 ms ,bat 关颜色 4.24 ms (同一次 -r 20 导出;和上面 -r 30 终测略有浮动,短命令正常)。
实测 4:参数化 -L 与 -P
-L / --parameter-list:离散列表
bash
hyperfine -w 2 -r 15 -L delay 0,0.05,0.1 'sleep {delay}'
| 命令 | 均值 | 中位数 |
|---|---|---|
sleep 0 |
3.7 ms | 4.0 ms |
sleep 0.05 |
52.3 ms | 52.9 ms |
sleep 0.1 |
103.7 ms | 103.9 ms |
相对倍数会自动打在终端上(本机 sleep 0.1 相对 sleep 0 约 27.9×)。
-P / --parameter-scan:数值扫描
bash
hyperfine -w 1 -r 10 -P n 0 3 -D 1 'sleep 0.0{n}'
本机得到 sleep 0.00 → 0.03:均值约 3.5 / 12.8 / 23.6 / 32.7 ms 。需要 $((...))、管道、&& 这类 shell 语法时,必须加 -S(见踩坑)。
踩坑清单(都在本机碰到过)
坑 1:apt 找不到 hyperfine 包
text
$ sudo apt-get install -y hyperfine
E: Unable to locate package hyperfine
和 bat 那篇一样:别在源里死磕,直接下 GitHub release 二进制或官方 .deb。
坑 2:2.0 默认 --shell=none,写 && / > 会直接报错
text
$ hyperfine 'true && echo ok'
Error: Command 'true && echo ok' contains unquoted shell syntax ('&&').
Explicitly choose how to execute it:
-S / --shell=default Interpret shell syntax.
-N / --shell=none Run directly, passing '&&' as a literal argument.
1.x 习惯「命令进 shell」的人,升到 2.0 会集体踩这个。需要重定向、管道、串联时加 -S ;确定要裸 exec 就 -N(默认已是 none)。
顺带:默认不走 shell 时,true 找到的是 /usr/bin/true 可执行文件,不是 bash builtin;要用 builtin 语义,显式 -S。
坑 3:stdout 默认被吞,调试要 --show-output
不加任何选项时,被测命令的打印不会出现在终端------测速干净,排错抓狂。本机对比:
bash
hyperfine -r 2 'echo HELLO_FROM_BENCH' # 看不到 HELLO
hyperfine -r 2 --show-output 'echo HELLO_FROM_BENCH' # 每次跑都打印
命令「看起来没跑」时,先加 --show-output,别先怀疑 hyperfine 坏了。
坑 4:极快命令 + 太少 runs,相对倍数会晃
本机 -r 3 比 true 和 /bin/true:有时显示 2.3× faster,有时反过来。拉到 -w 10 -r 100 后结论仍可能在噪声里翻面。亚毫秒~数毫秒级对比,不要写进标题当「结论」 ;看 σ 是否和差值一个量级。hyperfine 自己也会警告:带 shell 时低于约 5ms 的墙钟测量校准不准,建议改 -N。
坑 5:命令内 > /dev/null 也是 shell 语法
text
$ hyperfine 'cat file > /dev/null'
Error: ... unquoted shell syntax ('>') ...
要么 -S 'cat file > /dev/null',要么干脆让 hyperfine 自己吞输出(默认行为),不必再重定向。
顺手好用的几个参数
bash
hyperfine -w 3 -r 20 'cmd' # 预热 + 钉死次数
hyperfine -L n 1,2,4 'cmd {n}' # 离散参数
hyperfine -P n 1 8 -D 1 'cmd {n}' # 扫描参数
hyperfine -S 'cmd && other' # 需要 shell 时
hyperfine --export-markdown out.md # 均值表
hyperfine --export-json out.json # 含中位数/每次 runs(schema 2)
hyperfine --show-output 'cmd' # 调试输出
hyperfine --ignore-failure 'cmd' # 非零退出也继续测
小结
| 项 | 本机结果 |
|---|---|
| 版本 | hyperfine 2.0.0,星数约 2.9 万(2026-11-06) |
sleep 0.05 |
均值 52.4 ms / 中位 52.5 ms(-w 3 -r 20) |
| 2.96MB 复测 bat | cat 中位 3.0 ms ;关颜色 16.4 ms;开高亮 2.39 s (约 870×) |
| 6.67MB 关颜色 | cat 1.07 ms;bat 28.0 ms(约 26×) |
| 导出 | Markdown 均值表;JSON schema 2 含 median |
-L delay 0,0.05,0.1 |
均值 3.7 / 52.3 / 103.7 ms |
| 坑 | apt 无包;v2 默认不走 shell;stdout 被吞;短命令噪声;> 也要 -S |
一句话:hyperfine 把「我手写循环数中位数」升级成可导出、带相对倍数的基准流程;2.0 起默认不进 shell,写管道和 && 之前先想清楚要不要 -S。 它和 bat、fd、ripgrep 一样,默认很友好,但默认真相要用本机数字说话。
完整测量日志在本机 hyperfine/measurements.txt 与若干 export-*.json;整理版以后会放到 Gumroad,先关注专栏「GitHub实测笔记」。
上一篇:bat 本机实测(6.7MB JS 开高亮 12.4s / cat 1.2ms)。
下一篇预告:sharkdp/hexyl------十六进制查看器,继续 sharkdp 友好 CLI 线,看大文件/管道场景和 xxd/od 差在哪。有问题评论区见,看到都会回。