hyperfine 本机实测:2.96MB 上 bat 开高亮中位数 2.39s、cat 3.0ms(约 870 倍);v2 默认不走 shell

5 阅读5分钟

上一篇写完 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,等价于「输出不影响终端刷新」的测法。


本机环境

OS:        Debian 13 x86_64,8 核
hyperfine: 2.0.0(GitHub release 二进制)
bat:       0.26.1(上一篇同款)
cat:       GNU coreutils 9.7

安装又踩了和 bat / fd 一样的 apt 坑:

$ sudo apt-get install -y hyperfine
E: Unable to locate package hyperfine

本机 Debian 源里直接没有包。改走官方 release(与 bat 同一套路):

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.py2.96 MB上一篇高亮成本的主角之一
large_js.js6.67 MB关颜色吞吐对照

为什么不用手写 time 循环?

对 sleep 0.05 各跑 10 次。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:

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.py2.8 ms3.0 ms1×
bat --paging=never --color=never17.5 ms16.4 ms≈6.4×
bat --paging=never --color=always2399 ms2393 ms≈870×

结论和上一篇同向:关颜色大约慢一个数量级内;一开高亮就到约 2.39 秒。绝对数字和手写循环略有出入(今天 cat 中位数约 3.0ms,上次约 0.94ms——短命令本身噪声大,且两次测法、runs 数不同),但「开高亮贵三个数量级」这个故事站得住。hyperfine 额外给出了 σ(开高亮仅 ±19 ms)和相对倍数,不用自己算。

6.67MB JS 关颜色对照(-w 2 -r 10):

命令均值中位数
cat large_js.js1.1 ms1.07 ms
bat --paging=never --color=never28.1 ms28.0 ms

关颜色大约 26×。开高亮上一篇已测到 12.4s,今天没再烧时间重跑秒级高亮;需要时把上面第三条命令的文件换成 large_js.js 即可。

130KB typing.py(-w 3 -r 30):

命令均值中位数
cat0.50 ms0.50 ms
bat --color=never3.75 ms3.86 ms

关颜色大约 7.4×,和上一篇「约 6.8×」同一量级。

可复现:

# 预热文件进页缓存
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 519.7 ms先白跑 3 次再计入统计

I/O 相关命令建议至少 -w 1;对比短命令可以把 -w 拉到 3~10。
--runs / -r 钉死次数;不写 -r 时 hyperfine 会按稳定性自动加跑——本机对 sleep 0.001 自动跑到了 1046 次。短命令想少花时间,用 -r 或同时设 --max-runs。


实测 3:导出 JSON / Markdown

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 导出的是均值,主键指标):

CommandMean Wall Time [ms]ChangeFactor
cat …/typing.py1.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:离散列表

hyperfine -w 2 -r 15 -L delay 0,0.05,0.1 'sleep {delay}'
命令均值中位数
sleep 03.7 ms4.0 ms
sleep 0.0552.3 ms52.9 ms
sleep 0.1103.7 ms103.9 ms

相对倍数会自动打在终端上(本机 sleep 0.1 相对 sleep 0 约 27.9×)。

-P / --parameter-scan:数值扫描

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 包

$ sudo apt-get install -y hyperfine
E: Unable to locate package hyperfine

和 bat 那篇一样:别在源里死磕,直接下 GitHub release 二进制或官方 .deb。

坑 2:2.0 默认 --shell=none,写 && / > 会直接报错

$ 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

不加任何选项时,被测命令的打印不会出现在终端——测速干净,排错抓狂。本机对比:

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 语法

$ hyperfine 'cat file > /dev/null'
Error: ... unquoted shell syntax ('>') ...

要么 -S 'cat file > /dev/null',要么干脆让 hyperfine 自己吞输出(默认行为),不必再重定向。


顺手好用的几个参数

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 复测 batcat 中位 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 差在哪。有问题评论区见,看到都会回。