mcpField
H
hyperfine

hyperfine

官方Agent-ready
github.com开发者工具29.2khyperfine2 周前更新
代码仓库访问官网

关于 hyperfine

hyperfine 用统计分析的方法对命令行程序的性能进行基准测试。支持热预热和多轮测试,能够生成详细的性能对比报告,帮助开发者识别瓶颈和优化机会。

主要功能

  1. 01多次运行命令并计算执行时间的统计数据
  2. 02执行预热轮次以排除冷启动影响
  3. 03并行或顺序比较多个命令的性能
  4. 04输出时间分布、平均值、标准差等详细指标

适用场景

  1. 01比较不同实现或算法的运行时性能
  2. 02验证代码优化是否产生可测量的改进
  3. 03在 CI 环境中追踪性能回归

安装

选择你的系统或包管理器,复制命令到终端运行。

$
brew install hyperfine

安装完成后运行hyperfine --version确认安装成功。

命令示例

常用命令按使用顺序排列。

01
hyperfine "npm run build"
02
hyperfine --warmup 3 "rg TODO"

详细介绍

hyperfine

一款命令行基准测试工具。

hyperfine-demo-800

(hyperfine 实战演示:对 mypy 和 ty 进行基准测试)

功能

  • 对多次运行进行统计分析。
  • 支持多种性能指标和硬件计数器。
  • 支持任意 Shell 命令。
  • 持续反馈基准测试进度和当前估算结果。
  • 可在实际基准测试前执行预热运行。
  • 可设置在每次基准测试运行前执行的缓存清理命令。
  • 通过统计异常值检测,发现其他程序造成的干扰和缓存影响。
  • 将结果导出为多种格式:CSV、JSON、Markdown、AsciiDoc。
  • 参数化基准测试(例如,改变线程数)。
  • 跨平台

用法

基本基准测试

要运行基准测试,只需调用 hyperfine <command>...。每个参数都是一个可执行文件 及其参数。默认情况下,命令会直接运行;使用 -S 可启用管道、重定向和通配符等 Shell 语法。例如:

hyperfine 'sleep 0.3'

Hyperfine 会自动确定每个命令的运行次数。默认情况下,它至少会进行 10 次基准测试运行, 并估算运行次数,使总时长约为 3 秒,其中包括 Shell 开销以及准备和结束命令的耗时。若要 设置确切的运行次数,可以使用 -r/--runs 选项:

hyperfine --runs 5 'sleep 0.3'

若要比较不同的程序,可以传入多个命令:

hyperfine 'hexdump file' 'xxd file'

命令会按输入顺序运行并显示。第一个命令是所有比较的基准; 后续每个结果都会显示相对于该基准的变化。

预热运行和准备命令

对于大量执行磁盘 I/O 的程序,基准测试结果很容易受到磁盘缓存的影响, 具体取决于缓存是冷的还是热的。

若要在热缓存状态下运行基准测试,可以使用 -w/--warmup 选项, 在实际基准测试前执行一定次数的程序:

hyperfine -S --warmup 3 'grep -R TODO *'

相反,若要在冷缓存状态下运行基准测试,可以使用 -p/--prepare 选项,在每次基准测试运行前执行专用命令。例如,要清除 Linux 文件系统缓存, 可以运行

sync; echo 3 | sudo tee /proc/sys/vm/drop_caches

要在 hyperfine 中使用此特定命令,请调用 sudo -v 临时获取 sudo 权限, 然后调用:

hyperfine -S --prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' 'grep -R TODO *'
参数化基准测试

若要运行一系列基准测试并改变单个参数(例如线程数),可以使用 -P/--parameter-scan 选项,并调用:

hyperfine --prepare 'make clean' --parameter-scan num_threads 1 12 'make -j {num_threads}'

此选项也适用于小数。可以使用 -D/--parameter-step-size 选项 控制步长:

hyperfine --parameter-scan delay 0.3 0.7 -D 0.2 'sleep {delay}'

这会运行 sleep 0.3、sleep 0.5 和 sleep 0.7。

对于非数值参数,也可以使用 -L/--parameter-list 选项提供值列表:

hyperfine -L compiler g++,clang++ '{compiler} -O2 main.cpp'

一个常见用例是比较同一命令在多个 Git 分支上的表现。使用 --setup 在每组基准测试运行前切换一次分支,这样分支切换就不会计入被测命令的耗时:

hyperfine \
    --parameter-list branch main,performance-improvements \
    --setup 'git switch {branch}' \
    'python main.py'

如果需要为基准测试命令的每次单独运行提供唯一值,hyperfine 还会在被测命令内部提供 从零开始计数的 $HYPERFINE_ITERATION 环境变量:

hyperfine -S 'my-command > output-${HYPERFINE_ITERATION}.log'
中间 Shell

默认情况下,基准测试命令(包括预热运行)会直接执行,不经过中间 Shell(--shell=none)。 参数会按照类似 Shell 的引号规则拆分,因此支持包含空格的带引号参数。 管道、重定向、环境变量展开、* 和 ~ 等 Shell 语法不会被解释。 这样可以避免 Shell 启动开销,以及校正该开销所带来的测量噪声,尤其适用于快速命令 (< 5 ms)。

包含未加引号的独立 Shell 运算符(如 && 或 >)的命令需要显式选择:使用 -S / --shell=default 来解释 Shell 语法,或使用 -N / --shell=none 将这些运算符作为字面参数传递。

若要启用 Shell 语法,请使用 -S(即 --shell=default 的别名)。此选项会在 Unix 上选择 sh (通过 PATH 查找),或在 Windows 上选择 cmd.exe:

hyperfine -S 'sleep 0.1 && echo done'

你也可以使用 --shell <SHELL> 选择特定 Shell:

hyperfine --shell zsh 'for i in {1..10000}; do echo test; done'

--setup、--prepare、--conclude 和 --cleanup 命令始终通过 Shell 运行。 它们使用由 --shell 选择的 Shell;若省略 --shell 或将其设为 none,则使用平台 Shell(Unix 上为 sh,Windows 上为 cmd.exe)。

基准测试命令通过 Shell 运行时,hyperfine 会校正 Shell 启动时间。它会使用空命令多次运行 Shell,以测量其启动时间,然后从每次时间测量中减去该时间。

Shell 函数

如果你使用 bash,可以导出 Shell 函数,以便直接使用 hyperfine 对其进行基准测试:

my_function() { sleep 1; }
export -f my_function
hyperfine --shell=bash my_function

否则,请将函数内联到基准测试命令中:

hyperfine -S 'my_function() { sleep 1; }; my_function'
环境变量

使用 --env 为基准测试命令及其各自的 setup、prepare、conclude 和 cleanup 命令设置环境变量。赋值之间以空格分隔,并支持 Shell 风格的引号,但不支持 Shell 展开:

hyperfine --env 'OMP_NUM_THREADS=8 CFLAGS="-O3 -march=native"' 'my_command'

可以为所有命令指定一次,也可以为每个基准测试命令分别指定:

hyperfine \
  --env 'OMP_NUM_THREADS=8' './benchmark-cpp' \
  --env 'RAYON_NUM_THREADS=8' './benchmark-rust'

若不需要覆盖任何变量,请使用空值 --env=''。值中可以包含参数占位符。 例如,以下示例会对 my_command 进行基准测试,并将 OMP_NUM_THREADS 从 1 逐步设为 8:

hyperfine -P threads 1 8 --env 'OMP_NUM_THREADS={threads}' 'my_command'
选择指标和单位

默认情况下,hyperfine 会显示墙上时钟时间和内存用量 (time_wall_clock,memory_peak_resident)。使用 --metrics 和 逗号分隔的列表可选择不同的指标集。每个指标后都可以选择添加单位:

hyperfine \
    --metrics memory_peak_resident:MiB,time_wall_clock:ms,instructions \
    './baseline' './candidate'

以下指标可用:

  • time_wall_clock:从开始到结束所用的时间,包括等待时间,单位为秒。

  • time_user:以用户模式执行应用程序和库代码所用的 CPU 时间,按线程求和,单位为秒。

    • Linux/macOS:包括父进程等待子进程完成时的子进程时间。
    • Windows:包括命令及其子进程。
  • time_system:代表程序执行内核代码所用的 CPU 时间,例如读取文件所需的时间,按线程求和,单位为秒。

    • Linux/macOS:包括父进程等待子进程完成时的子进程时间。
    • Windows:包括命令及其子进程。
  • time_cpu:总 CPU 时间,每次运行均按 time_user + time_system 计算,单位为秒。 不包括休眠或等待期间未执行任务的时间。CPU 时间按线程求和,因此可能超过墙上时钟时间:四个线程在四个核心上运行一秒,大约会消耗四个 CPU 秒。

  • memory_peak_resident:物理 RAM 中占用的峰值内存,单位为字节。

    • Linux/macOS:最大常驻集大小(RSS)。这是命令及其子进程各自的进程峰值中的最大值(父进程等待子进程时会收集其用量),而不是整个进程树同时占用的总内存。在 Linux 上,测量峰值 RSS 非常小(低于 hyperfine 启动时继承的峰值,可能为数 MiB)的命令时,目前会报告该继承值。
    • Windows:目前不支持。
  • cpu_cycles:消耗的 CPU 周期数。

    • Linux:包括线程和子进程,但不包括内核和虚拟机监控程序的执行。
    • macOS:包括进程的线程和内核执行,但不包括子进程。
    • Windows:目前不支持。
  • instructions:已完成的 CPU 指令数。

    • Linux/macOS:范围与 cpu_cycles 相同。
    • Windows:目前不支持。
  • cache_references:由 CPU 的通用缓存事件统计的缓存访问次数。

    • Linux:范围与 cpu_cycles 相同。缓存事件的定义取决于 CPU。
    • macOS/Windows:目前不支持。
  • cache_misses:缓存未命中次数。

    • Linux:范围与 cpu_cycles 相同。缓存事件的定义取决于 CPU。
    • macOS/Windows:目前不支持。
  • branch_misses:分支预测失败次数。

    • Linux:范围与 cpu_cycles 相同。
    • macOS/Windows:目前不支持。

请注意,启用 shell(--shell=..)时无法使用硬件计数器。

时间测量支持 ns、us、ms、s、min 和 h 单位。内存测量支持 B、kB、MB、GB、TB、KiB、MiB、GiB 和 TiB 单位。硬件计数器 支持 count(1)、k(千)、M(百万)和 B(十亿)。

你还可以使用预设来选择一组指标:

预设指标
--metrics=defaulttime_wall_clock,memory_peak_resident
--metrics=timetime_wall_clock,time_cpu,time_user,time_system
--metrics=all所有可用指标
导出结果

Hyperfine 可以将结果导出为 CSV、JSON、Markdown、AsciiDoc 和 org-mode 格式。CSV 会导出所有已选指标,而 Markdown、AsciiDoc 和 org-mode 只包含主要指标,即通过 --metrics 选择的第一个指标。

Markdown

你可以使用 --export-markdown <file> 选项创建如下表格:

命令平均耗时 [秒]变化倍数
find . -iregex '.*[0-9]\.jpg$'2.275 ± 0.046
find . -iname '*[0-9].jpg'1.427 ± 0.026-37.3%(快 1.6 倍)
fd -HI '.*[0-9]\.jpg$'0.232 ± 0.002-89.8%(快 9.8 倍)
JSON

JSON 导出会包含每次测量运行的可选指标和单位中列出的所有可用指标(不包括预热运行)。

如果你想进一步分析基准测试结果,JSON 输出会很有用。 scripts/ 文件夹中包含许多实用的 Python 程序,可用于进一步分析基准测试结果,并创建直方图(显示运行时间分布)或须状图(对比多项基准测试)等可视化图表。

例如,以下两条命令会生成这些图表:

uvx --from 'git+https://github.com/sharkdp/hyperfine' \
  plot_histogram results.json
uvx --from 'git+https://github.com/sharkdp/hyperfine' \
  plot_whisker results.json
README 配图README 配图
CSV

使用 --export-csv <file> 可为每条命令导出一行。--metrics 选中的每项指标都会按所选顺序生成一组列:<metric>_unit、<metric>_mean、<metric>_stddev、<metric>_median、<metric>_min 和 <metric>_max。

CSV 使用明确选定的单位;如果未指定,则使用基本单位(秒、字节或计数)。

详细的基准测试流程图

下图说明了使用 --warmup、--prepare <cmd>、--setup <cmd> 或 --cleanup <cmd> 等选项时,各基准测试运行的执行顺序:

README 配图

安装

打包状态

在 Ubuntu 上

在 Ubuntu 上,可以从官方仓库安装 hyperfine:

apt install hyperfine

此外,要安装最新版本,可以从发布页面下载合适的 .deb 软件包,并通过 dpkg 安装:

wget https://github.com/sharkdp/hyperfine/releases/download/v2.0.0/hyperfine_2.0.0_amd64.deb
sudo dpkg -i hyperfine_2.0.0_amd64.deb
在 Fedora 上

在 Fedora 上,可以从官方仓库安装 hyperfine:

dnf install hyperfine
在 Alpine Linux 上

在 Alpine Linux 上,可以从官方仓库安装 hyperfine:

apk add hyperfine
在 Arch Linux 上

在 Arch Linux 上,可以从官方仓库安装 hyperfine:

pacman -S hyperfine
在 Debian Linux 上

在 Debian Linux 上,可以从官方仓库安装 hyperfine:

apt install hyperfine
在 Exherbo Linux 上

在 Exherbo Linux 上,可以从 rust 仓库安装 hyperfine:

cave resolve -x repository/rust
cave resolve -x hyperfine
在 NixOS 上

在 NixOS 上,可以从官方仓库安装 hyperfine:

nix-env -i hyperfine
在 Flox 上

在 Flox 上,可以按以下方式安装 hyperfine。

flox install hyperfine

Flox 中的 Hyperfine 版本与 Nix 中的版本一致。

在 openSUSE 上

在 openSUSE 上,可以从官方仓库安装 hyperfine:

zypper install hyperfine
在 Void Linux 上

可以通过 xbps 安装 Hyperfine

xbps-install -S hyperfine
在 macOS 上

可以通过 Homebrew 安装 Hyperfine:

brew install hyperfine

也可以使用 MacPorts 安装:

sudo port selfupdate
sudo port install hyperfine
在 FreeBSD 上

可以通过 pkg 安装 Hyperfine:

pkg install hyperfine
在 OpenBSD 上
doas pkg_add hyperfine
在 Windows 上

可以通过 Chocolatey、Scoop 或 Winget 安装 Hyperfine:

choco install hyperfine
scoop install hyperfine
winget install hyperfine
使用 conda

可以通过 conda 从 conda-forge 频道安装 Hyperfine:

conda install -c conda-forge hyperfine
使用 cargo(Linux、macOS、Windows)

可以通过 cargo 从源代码安装 Hyperfine:

cargo install --locked hyperfine

请确保使用 Rust 1.97 或更高版本。

从二进制文件安装(Linux、macOS、Windows)

从 Release 页面下载相应的压缩包。

替代工具

Hyperfine 的灵感来源于 bench。

与其他工具集成

Chronologer 是一款使用 hyperfine 可视化 Git 历史中基准测试耗时变化的工具。

Bencher 是一款持续基准测试工具,支持使用 hyperfine 跟踪基准测试,并在 CI 中发现性能回退。

将 hyperfine 的 JSON 输出拖放到 Venz 图表中,即可可视化结果并管理 hyperfine 配置。

请查看此仓库中的 scripts 文件夹,其中包含一系列用于处理 hyperfine 基准测试结果的工具。

名称由来

名称 hyperfine 是为纪念铯 133 的超精细能级而选定的,它们在基本时间单位的定义中发挥着关键作用——这个单位就是秒。

引用 hyperfine

感谢您考虑在研究工作中引用 hyperfine。有关如何正确引用 hyperfine 的信息,请参阅侧边栏。

许可证

hyperfine 根据 MIT 许可证和 Apache 许可证 2.0 的条款双重授权。

详情请参阅 LICENSE-APACHE 和 LICENSE-MIT 文件。

评论

支持 Markdown