惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
N
Netflix TechBlog - Medium
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
IT之家
IT之家
博客园_首页
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
M
MIT News - Artificial intelligence
博客园 - Franky
C
Check Point Blog
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
云风的 BLOG
云风的 BLOG
美团技术团队
The Cloudflare Blog
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
V
V2EX
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
G
Google Developers Blog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
罗磊的独立博客
量子位
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
D
Docker
人人都是产品经理
人人都是产品经理

暗无天日

读:AI Agent 安全日志——从可见性与隐私的两难说起 - 暗无天日 读:AI Agent 生产化——一份从原型到上线的速查清单 - 暗无天日 AI写作的语言指纹——如何让文字不那么像机器 - 暗无天日 读:50 条 Claude Code 技巧——一个工程经理的六个月使用心得 读:AI 辅助开发为什么让 E2E 测试更有价值 - 暗无天日 读:在Emacs中使用Claude Code(Spacemacs适配版) - 暗无天日 Claude Code 背后的工程哲学——读 Agent Harness Engineering 读:Agent Harness Engineering——AI 智能体不只是模型,还有套件 - 暗无天日 browser-harness:让 AI 直接接管你的浏览器 - 暗无天日 读:Security-First CI/CD —— DevSecOps 自动化实践指南 TIL: 数字小键盘的小数点陷阱与行内算术求值 - 暗无天日 读:Immutability 不是万能药,它是一种权衡 - 暗无天日 Conducty:给 Claude Code 加上项目记忆和并行执行能力 - 暗无天日 读 — GitHub Trending 里的 Claude Code 技能包 读 — Prompt Caching 省钱指南 TIL: Emacs 中那些跟鼠标配合的冷门快捷键 - 暗无天日 读:Anvil——把 Emacs 变成 AI 的工具服务器 读:Emacs 代码折叠终极指南 - 暗无天日 读:Clojure 搭车客指南 - 暗无天日 git推送失败后恢复仓库损坏的完整记录 - 暗无天日 多智能体系统的两个有效模式——以及对 Claude Code 用户的启示 - 暗无天日 用 Org Babel 写 Literate 博文:扩展执行 + 定制导出 proced:Emacs 内置的进程查看器 - 暗无天日 从 proced 定制中学到的 Elisp 模式 读:让 Emacs proced 在 macOS 上显示 CPU 和内存 异步编程的函数着色税 - 暗无天日 链式调用的代价:JavaScript 和 Clojure 的共同教训 - 暗无天日 管道中的变量去哪了?——子 shell 作用域陷阱 - 暗无天日 开源包装器的信任陷阱:四个危险信号 - 暗无天日 程序员愿意为 AI 写文档,却不愿为同事写 - 暗无天日 mktemp: Shell 脚本中临时文件的安全陷阱与最佳实践 - 暗无天日 WSL9x —— 在 Windows 9x 里跑 Linux 内核 6.19 用 ox.el 做你想做的事 —— org-export 高级编程指南 读:Hot-wiring the Lisp Machine —— 用纯 Elisp 构建零依赖的 Org 静态站点生成器 Elisp 性能优化的六个实战教训 - 暗无天日 fcitx5 下 Emacs 无法切换输入法的排查 - 暗无天日 ERT 测试交互命令的三种方式 - 暗无天日 SEM Assistant: 当 Elisp 守护进程遇上 LLM 用 dmsg 给 Elisp 加上结构化调试日志 用 org-habit 追踪非每日习惯 - 暗无天日 Clojure X-Men:当编程语言特性变成超能力 - 暗无天日 TIL: 用 diff-hl 在 fringe 中显示 git 变更 读:llm-test —— 用 LLM agent 驱动 Emacs 测试 TIL: AI 时代的橡皮鸭调试 - 暗无天日 fcitx 启动后键盘输入卡顿的排查 - 暗无天日 TIL: 早期网页的图片热区导航 - 暗无天日 读 Seeing the Whole System 用 Emacs 自动生成每周链接推荐 - 暗无天日 读:ASCII control characters in my terminal 读 What to learn - 暗无天日 Lisp 的括号之痛——一个愚人节玩笑揭开的老伤疤 - 暗无天日 一本书该"线性读"还是"并行读" - 暗无天日 读 How to Monetize a Blog:一篇伪装成变现指南的讽刺文 Python Mock 第三方依赖的四种策略 - 暗无天日 Emacs Lisp 热重载实用指南 - 暗无天日 Prot 的 Emacs 配置哲学 - 暗无天日 TIL: 从直播对谈中学到的三个 Emacs 技巧 - 暗无天日 TIL: 自动使用项目虚拟环境的 Python - 暗无天日 TIL: 让 Help buffer 自动获得焦点 一条命令让本地开发用上 HTTPS —— slim 工具介绍 用 fsck 检查和修复 Linux 文件系统 排查Linux进程"卡死"实战:从strace到gdb全流程 - 暗无天日 PostgreSQL 索引:从基础到你可能不知道的高级用法 - 暗无天日 用 .pdbrc 自定义 Python 调试器 ANSI 转义码的标准化现状 - 暗无天日 终端程序的潜规则 - 暗无天日 PARA Org-mode 测试配置 - 暗无天日 AI越强越辣鸡?控制论说这是必然的 - 暗无天日 AI 越强越需要你盯着——反馈循环实操指南 - 暗无天日 你的AI代理正在偷你的密钥——四种你没想到的泄露通道 - 暗无天日 LLM 在 DevOps 中的三种角色 - 暗无天日 写作风格的反建议 - 暗无天日 反驳本质复杂性——Dan Luu 论为什么《没有银弹》错了 - 暗无天日 文件充满了危险——Dan Luu 谈文件系统的可靠性陷阱 - 暗无天日 AI 时代的 PARA 方法:用 Org-mode 和 AI 打造个人知识管理系统 Linux 数据去重学习笔记 - 暗无天日 创建跨平台 ZIP 文件的隐藏陷阱:Extra Field - 暗无天日 X11 Forwarding 排障指南 - 暗无天日 IP欺骗端口扫描:当别人冒充你去扫描别人 - 暗无天日 Linux 输入栈全景解析:从硬件按键到屏幕响应 - 暗无天日 Unix 系统中那些被埋没的配置开关——以 FontConfig 为例 - 暗无天日 在Linux上限制儿童使用电脑 - 暗无天日 GIF不仅仅是一种图片格式——用GIF流做些奇怪的事 - 暗无天日 Leiningen 学习笔记:Clojure 项目构建与管理从入门到实战配置 - 暗无天日 Google SRE Book 读书笔记 - 暗无天日 yes 管道 head 发生了什么 - 暗无天日 为什么 nohup 在 crontab 中不起作用 Bash中的Indirection与Nameref - 暗无天日 Linux PAM 简介 - 暗无天日 从Linux ISO文件启动计算机 - 暗无天日 用 Bash 打造一个Screen Locker 用GitHub Actions自动构建EGO博客 - 暗无天日 blocking I/O 的作用 - 暗无天日 mobileog 手机端同步提示Error:2 No such file 的解决方法 回收 WSL2 VHDX 文件占用空间 使用 org-mode columnview 生成任务列表 - 暗无天日 Emacs 作为 MPD 客户端 - 暗无天日 移动文件路径却不破坏org file link的方法 - 暗无天日 如何合理的导出help link 成HTML - 暗无天日 笑话理解之Biology - 暗无天日
hyperfine:命令行基准测试工具 - 暗无天日
2026-04-25 · via 暗无天日

测一个命令要跑多久,大多数人第一反应是 time

time find /usr/share/doc -maxdepth 2 -name "*.txt"
real	0m0.012s
user	0m0.004s
sys	0m0.007s

但跑第二次,结果可能变成 0.009s ;第三次 0.015s 。哪一个才是"真实"的执行时间?

磁盘缓存、CPU 调度、后台进程、甚至 CPU 频率调节( turbo boost )都会让每次执行时间不同。你需要的是多次采样的统计摘要——均值、标准差、最小/最大值——而不是一个孤立的数字。

hyperfine 可以帮我们自动处理采样、预热和统计分析。

基本用法

最简单的形式:把命令放在引号里。

hyperfine 'find /usr/share/doc -maxdepth 2 -name "*.txt"'
Benchmark 1: find /usr/share/doc -maxdepth 2 -name "*.txt"
  Time (mean ± σ):      20.2 ms ±  23.0 ms    [User: 5.4 ms, System: 10.7 ms]
  Range (min … max):    12.0 ms … 125.3 ms    23 runs

  Warning: The first benchmarking run for this command was significantly slower than
  the rest (125.3 ms). This could be caused by (filesystem) caches that were not
  filled until after the first run. You should consider using the '--warmup' option.

hyperfine 甚至会主动告诉你问题在哪里——第一次运行明显慢于后续( 125.3ms vs 12.0ms ),因为文件系统缓存还没热。这正是后面要讲的 --warmup 要解决的问题。

输出解读:

  • Time (mean ± σ) :均值 ± 标准差。标准差越小,说明结果越稳定。
  • [User: ... System: ...] :用户态和内核态的 CPU 时间。
  • Range (min … max) :最快和最慢的一次,展示了波动范围。
  • 23 runshyperfine 自动决定了跑 23 次(默认至少 10 次,且至少测量 3 秒)。

对比两个命令

hyperfine 真正有用的地方是对比。传多个命令就行:

hyperfine --warmup 2 'grep -r "error" /var/log/' 'rg "error" /var/log/'
Benchmark 1: grep -r "error" /var/log/
  Time (mean ± σ):     370.7 ms ±  12.1 ms    [User: 308.5 ms, System: 58.9 ms]
  Range (min … max):   355.8 ms … 396.4 ms    10 runs

Benchmark 2: rg "error" /var/log/
  Time (mean ± σ):      12.5 ms ±   3.1 ms    [User: 9.1 ms, System: 10.1 ms]
  Range (min … max):     8.6 ms …  31.0 ms    244 runs

Summary
  rg "error" /var/log/ ran
   29.62 ± 7.46 times faster than grep -r "error" /var/log/

最后一行 Summary 直接给出了倍数比较。这个数字可以直接用在技术讨论或 PR 里——不是"感觉快了不少",而是"快了 29.6 倍,误差 ±7.5 倍"。

控制采样参数

--runs N :指定执行次数

慢命令(数据库导出、大文件压缩)跑 10 次太浪费时间,可以减少:

hyperfine --runs 3 'tar -czf /tmp/test-backup.tar.gz /usr/share/doc'
Benchmark 1: tar -czf /tmp/test-backup.tar.gz /usr/share/doc
  Time (mean ± σ):     11.022 s ±  0.423 s    [User: 9.798 s, System: 1.275 s]
  Range (min … max):   10.547 s … 11.357 s    3 runs

快命令(毫秒级)则应该增加次数来稳定统计:

hyperfine --runs 50 'md5sum /tmp/testfile'
Benchmark 1: md5sum /tmp/testfile
  Time (mean ± σ):      11.8 ms ±   1.6 ms    [User: 9.4 ms, System: 2.1 ms]
  Range (min … max):    10.5 ms …  16.0 ms    50 runs

50 次跑下来,均值 11.8ms ,标准差只有 1.6ms ,统计上比 3 次可靠得多。

--warmup N :预热次数

如果你的命令涉及磁盘读取,第一次运行会冷启动(磁盘 I/O ),后续运行会命中缓存。 --warmuphyperfine 在开始计时前先跑几轮:

hyperfine --warmup 3 'wc -l /var/log/pacman.log'
Benchmark 1: wc -l /var/log/pacman.log
  Time (mean ± σ):       4.7 ms ±   0.8 ms    [User: 2.4 ms, System: 2.1 ms]
  Range (min … max):     3.7 ms …   9.3 ms    524 runs

预热 3 次之后,标准差从可能的几十毫秒降到了 0.8ms 。对比基本用法中没有加 --warmup 的输出( σ=23.0ms ),效果很明显。

反过来,如果你想测冷启动性能,用 --prepare 在每次计时前执行准备命令:

hyperfine --prepare 'sync' 'find /usr/share/doc -maxdepth 2 -name "*.txt"'
Benchmark 1: find /usr/share/doc -maxdepth 2 -name "*.txt"
  Time (mean ± σ):      14.7 ms ±   2.2 ms    [User: 6.2 ms, System: 8.6 ms]
  Range (min … max):    11.9 ms …  19.7 ms    10 runs

sync 把文件系统缓冲区写回磁盘,做轻量级的缓存干扰。完整清除磁盘缓存需要 sync && echo 3 | sudo tee /proc/sys/vm/drop_caches ,但需要 root 权限。

参数化基准测试

这是 hyperfine 最强大也最容易被忽略的功能。 --parameter-scan 让你自动遍历一个参数的范围:

hyperfine --parameter-scan block_size 1024 8192 -D 2048 \
  'dd if=/dev/zero of=/tmp/ddtest bs={block_size} count=4096 2>/dev/null'
Benchmark 1: dd if=/dev/zero of=/tmp/ddtest bs=1024 count=4096 2>/dev/null
  Time (mean ± σ):      16.1 ms ±   5.5 ms    [User: 3.5 ms, System: 10.7 ms]
  Range (min … max):    11.7 ms …  41.0 ms    134 runs

Benchmark 2: dd if=/dev/zero of=/tmp/ddtest bs=3072 count=4096 2>/dev/null
  Time (mean ± σ):      21.7 ms ±   3.9 ms    [User: 3.6 ms, System: 17.0 ms]
  Range (min … max):    16.3 ms …  42.3 ms    110 runs

Benchmark 3: dd if=/dev/zero of=/tmp/ddtest bs=5120 count=4096 2>/dev/null
  Time (mean ± σ):      26.7 ms ±   3.8 ms    [User: 3.8 ms, System: 22.0 ms]
  Range (min … max):    20.5 ms …  38.2 ms    119 runs

Benchmark 4: dd if=/dev/zero of=/tmp/ddtest bs=7168 count=4096 2>/dev/null
  Time (mean ± σ):      31.3 ms ±   4.2 ms    [User: 3.8 ms, System: 26.6 ms]
  Range (min … max):    24.1 ms …  46.6 ms    106 runs

Summary
  dd bs=1024 ran
    1.34 ± 0.52 times faster than dd bs=3072
    1.65 ± 0.61 times faster than dd bs=5120
    1.94 ± 0.71 times faster than dd bs=7168

-D--parameter-step-size )控制步长。这里从 1024 到 8192 ,步长 2048 ,自动生成了 4 组测试。有趣的是,较小的块大小反而更快——因为 dd if=/dev/zero 是内存操作,小块大小意味着更少的系统调用开销。

-L--parameter-list )可以传非数值的参数列表,比如对比压缩工具:

hyperfine --prepare 'rm -f /tmp/testfile.{gz,bz2,zst}' \
  -L prog gzip,bzip2,zstd '{prog} -k /tmp/testfile'
Benchmark 1: gzip -k /tmp/testfile
  Time (mean ± σ):     199.1 ms ±   9.7 ms    [User: 191.6 ms, System: 5.2 ms]
  Range (min … max):   182.8 ms … 216.5 ms    15 runs

Benchmark 2: bzip2 -k /tmp/testfile
  Time (mean ± σ):      1.056 s ±  0.023 s    [User: 1.037 s, System: 0.010 s]
  Range (min … max):    1.023 s … 1.093 s    10 runs

Benchmark 3: zstd -k /tmp/testfile
  Time (mean ± σ):      22.5 ms ±   1.8 ms    [User: 13.6 ms, System: 14.6 ms]
  Range (min … max):    19.1 ms …  29.3 ms    99 runs

Summary
  zstd -k /tmp/testfile ran
    8.85 ± 0.82 times faster than gzip -k /tmp/testfile
   46.92 ± 3.83 times faster than bzip2 -k /tmp/testfile

这种参数化测试在脚本里手写非常繁琐——你需要自己写循环、解析 time 输出、计算统计量。 hyperfine 一行命令搞定。

注意 --prepare 的用法: gzip -kzstd -k 不会覆盖已存在的压缩文件,所以每次执行前必须清理。 --prepare 会在每轮计时前自动执行。

导出结果

命令行输出适合看,不适合分析。 hyperfine 支持导出为 JSON 和 Markdown :

hyperfine --prepare 'rm -f /tmp/testfile.{gz,zst}' \
  --export-markdown /tmp/result.md \
  'gzip -k /tmp/testfile' 'zstd -k /tmp/testfile'
Benchmark 1: gzip -k /tmp/testfile
  Time (mean ± σ):     199.5 ms ±   9.2 ms    [User: 192.6 ms, System: 4.5 ms]
  Range (min … max):   182.0 ms … 214.6 ms    14 runs

Benchmark 2: zstd -k /tmp/testfile
  Time (mean ± σ):      22.4 ms ±   2.1 ms    [User: 13.4 ms, System: 14.8 ms]
  Range (min … max):    15.6 ms …  28.3 ms    98 runs

Summary
  zstd -k /tmp/testfile ran
    8.89 ± 0.92 times faster than gzip -k /tmp/testfile

导出的 Markdown 文件可以直接贴进 GitHub issue 或文档:

cat /tmp/result.md
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|:---|---:|---:|---:|---:|
| `gzip -k /tmp/testfile` | 199.5 ± 9.2 | 182.0 | 214.6 | 8.89 ± 0.92 |
| `zstd -k /tmp/testfile` | 22.4 ± 2.1 | 15.6 | 28.3 | 1.00 |

--export-json 导出完整数据(每次运行的时间戳都保留),适合喂给脚本做进一步分析或绘制趋势图。

什么时候该用什么工具

需求 工具
快速看一眼执行时间 time command
对比两个命令谁更快 hyperfine 'cmd1' 'cmd2'
找最优参数(块大小、线程数) hyperfine --parameter-scan ...
CI 里追踪性能回归 hyperfine --export-json ... + 脚本对比
系统级性能分析(CPU、内存、I/O) perf / valgrind

hyperfine 测的是 墙钟时间 ( wall-clock time ),回答"这个命令跑多久"。如果你需要知道 为什么 慢( CPU 热点、内存分配、系统调用),那是 perfvalgrind 的领域。