2018-01-13 20:27:24 +01:00
# hyperfine
2019-06-08 14:29:07 +02:00
A command-line benchmarking tool.
2018-01-13 20:27:24 +01:00
2026-10-06 16:56:09 +02:00
<img width="839" height="205" alt="hyperfine demo" src="https://github.com/user-attachments/assets/13c20b1d-39c1-4da1-8fcb-0c775dd032f5" />
2018-01-14 22:19:52 +01:00
2026-10-06 17:39:19 +02:00
*(hyperfine in action, benchmarking [`mypy`](https://mypy-lang.org/) and [`ty`](https://ty.dev/))*
2018-01-13 21:31:51 +01:00
2018-01-13 20:27:24 +01:00
## Features
2018-01-20 14:22:26 +01:00
* Statistical analysis across multiple runs.
2026-10-06 17:39:19 +02:00
* Support for various performance metrics and hardware counters.
2018-01-20 14:22:26 +01:00
* Support for arbitrary shell commands.
* Constant feedback about the benchmark progress and current estimates.
* Warmup runs can be executed before the actual benchmark.
2026-10-06 15:50:19 +02:00
* Cache-clearing commands can be set up before each benchmark run.
2019-06-08 14:36:45 +02:00
* Statistical outlier detection to detect interference from other programs and caching effects.
* Export results to various formats: CSV, JSON, Markdown, AsciiDoc.
* Parameterized benchmarks (e.g. vary the number of threads).
2018-02-13 21:17:27 +01:00
* Cross-platform
2018-01-13 21:07:28 +01:00
2018-01-16 22:03:50 +01:00
## Usage
2022-03-05 12:39:00 +01:00
### Basic benchmarks
2018-01-16 22:03:50 +01:00
2026-10-06 08:41:59 +02:00
To run a benchmark, you can simply call `hyperfine <command>...` . Each argument is an executable
and its arguments. Commands run directly by default; use `-S` for shell syntax such as
pipes, redirections, and wildcards. For example:
2022-08-25 18:12:41 +02:00
```sh
2018-01-24 08:32:11 +01:00
hyperfine 'sleep 0.3'
2018-01-16 22:03:50 +01:00
```
2018-01-18 18:13:12 +01:00
Hyperfine will automatically determine the number of runs to perform for each command. By default,
2026-10-02 11:53:16 +02:00
it will perform *at least* 10 benchmarking runs and estimate a run count targeting roughly
3 seconds, including shell overhead and preparation and conclusion commands. To set an exact
number of runs, you can use the `-r` /`--runs` option:
2022-08-25 18:12:41 +02:00
```sh
2022-03-05 12:39:00 +01:00
hyperfine --runs 5 'sleep 0.3'
```
2026-10-06 15:50:19 +02:00
If you want to compare different programs, you can pass multiple commands:
2022-08-25 18:12:41 +02:00
```sh
2022-03-05 12:39:00 +01:00
hyperfine 'hexdump file' 'xxd file'
2018-01-16 22:03:50 +01:00
```
2026-10-06 15:50:19 +02:00
Commands run and appear in input order. The first command is the reference for all comparisons;
each subsequent result shows its change from that reference.
2019-10-13 16:24:46 +02:00
### Warmup runs and preparation commands
2018-01-16 22:03:50 +01:00
2022-03-05 12:39:00 +01:00
For programs that perform a lot of disk I/O, the benchmarking results can be heavily influenced
by disk caches and whether they are cold or warm.
2018-01-16 22:03:50 +01:00
2022-03-05 12:39:00 +01:00
If you want to run the benchmark on a warm cache, you can use the `-w` /`--warmup` option to
perform a certain number of program executions before the actual benchmark:
2022-08-25 18:12:41 +02:00
```sh
2026-10-06 08:41:59 +02:00
hyperfine -S --warmup 3 'grep -R TODO *'
2018-01-16 22:03:50 +01:00
```
2018-01-18 18:13:12 +01:00
Conversely, if you want to run the benchmark for a cold cache, you can use the `-p` /`--prepare`
2026-10-06 15:50:19 +02:00
option to run a special command before *each* benchmark run. For example, to clear Linux filesystem caches,
2026-10-02 11:52:14 +02:00
you can run
2022-08-25 18:12:41 +02:00
```sh
2018-01-16 22:03:50 +01:00
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
```
2022-03-05 12:39:00 +01:00
To use this specific command with hyperfine, call `sudo -v` to temporarily gain sudo permissions
2018-01-18 18:13:12 +01:00
and then call:
2022-08-25 18:12:41 +02:00
```sh
2026-10-06 08:41:59 +02:00
hyperfine -S --prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' 'grep -R TODO *'
2018-01-16 22:03:50 +01:00
```
2018-03-24 21:01:41 +01:00
### Parameterized benchmarks
2022-03-05 12:39:00 +01:00
If you want to run a series of benchmarks where a single parameter is varied (say, the number of
2018-03-24 21:01:41 +01:00
threads), you can use the `-P` /`--parameter-scan` option and call:
2022-08-25 18:12:41 +02:00
```sh
2018-03-24 21:01:41 +01:00
hyperfine --prepare 'make clean' --parameter-scan num_threads 1 12 'make -j {num_threads}'
```
2019-09-01 14:39:07 +02:00
This also works with decimal numbers. The `-D` /`--parameter-step-size` option can be used
to control the step size:
2022-08-25 18:12:41 +02:00
```sh
2019-09-01 15:01:20 +02:00
hyperfine --parameter-scan delay 0.3 0.7 -D 0.2 'sleep {delay}'
2019-09-01 14:39:07 +02:00
```
2019-09-01 15:01:20 +02:00
This runs `sleep 0.3` , `sleep 0.5` and `sleep 0.7` .
2018-03-24 21:01:41 +01:00
2022-03-05 12:39:00 +01:00
For non-numeric parameters, you can also supply a list of values with the `-L` /`--parameter-list`
option:
```
2026-10-02 11:46:04 +02:00
hyperfine -L compiler g++,clang++ '{compiler} -O2 main.cpp'
2022-03-05 12:39:00 +01:00
```
2026-06-01 15:49:59 +01:00
A common use case is comparing the same command across multiple Git branches. Use `--setup`
2026-10-06 15:50:19 +02:00
to switch branches once before each set of benchmark runs, so the branch switch is not part of
2026-06-01 15:49:59 +01:00
the measured command:
```sh
hyperfine \
--parameter-list branch main,performance-improvements \
--setup 'git switch {branch}' \
2026-10-05 11:53:24 +02:00
'python main.py'
2026-06-01 15:49:59 +01:00
```
2026-06-02 01:25:13 +10:00
If you need a unique value for each individual run of a benchmark command, hyperfine also exposes
the zero-based `$HYPERFINE_ITERATION` environment variable inside the benchmarked command itself:
```sh
2026-10-06 08:41:59 +02:00
hyperfine -S 'my-command > output-${HYPERFINE_ITERATION}.log'
2026-06-02 01:25:13 +10:00
```
2022-03-05 12:39:00 +01:00
### Intermediate shell
2026-10-07 10:53:52 +02:00
By default, benchmarked commands, including warmup runs, are executed directly, without an intermediate shell (`--shell=none` ).
2026-10-06 08:41:59 +02:00
Arguments are split using shell-like quoting, so quoted arguments containing spaces are supported.
Shell syntax such as pipes, redirections, environment-variable expansion, `*` , and `~` is not interpreted.
This avoids shell startup overhead and the noise from correcting for it, especially for fast commands
(< 5 ms).
2026-10-07 12:12:13 +02:00
Commands containing unquoted, standalone shell operators such as `&&` or `>` require an explicit
choice: use `-S` / `--shell=default` to interpret shell syntax, or `-N` / `--shell=none` to pass
the operators as literal arguments.
2026-10-06 08:41:59 +02:00
To enable shell syntax, use `-S` (an alias for `--shell=default` ). This selects `sh`
on Unix (resolved through `PATH` ) or `cmd.exe` on Windows:
```sh
hyperfine -S 'sleep 0.1 && echo done'
```
You can also select a specific shell with `--shell <SHELL>` :
2022-08-25 18:12:41 +02:00
```sh
2022-03-05 12:39:00 +01:00
hyperfine --shell zsh 'for i in {1..10000}; do echo test; done'
```
2026-10-07 10:53:52 +02:00
The `--setup` , `--prepare` , `--conclude` , and `--cleanup` commands always run through a shell.
They use the shell selected by `--shell` , or the platform shell (`sh` on Unix, `cmd.exe` on Windows)
when `--shell` is omitted or set to `none` .
2022-03-05 12:39:00 +01:00
2026-10-07 10:53:52 +02:00
When benchmarked commands use a shell, hyperfine *corrects for the shell spawning time* . It runs the shell with an
2026-10-06 08:41:59 +02:00
empty command multiple times to measure its startup time, then subtracts this time from each
2026-10-06 15:50:19 +02:00
time measurement.
2022-03-05 12:39:00 +01:00
2026-10-02 10:45:49 +02:00
### Shell functions
2020-10-26 15:37:01 -03:00
2022-10-13 22:43:09 +02:00
If you are using bash, you can export shell functions to directly benchmark them with hyperfine:
2020-10-26 15:37:01 -03:00
```bash
2022-08-25 18:12:41 +02:00
my_function() { sleep 1; }
export -f my_function
hyperfine --shell= bash my_function
```
2026-10-02 10:45:49 +02:00
Otherwise, inline the function into the benchmarked command:
2022-08-25 18:12:41 +02:00
```sh
2026-10-06 08:41:59 +02:00
hyperfine -S 'my_function() { sleep 1; }; my_function'
2020-10-26 15:37:01 -03:00
```
2026-10-06 15:50:19 +02:00
### Choosing metrics and units
2018-03-24 21:01:41 +01:00
2026-10-06 15:50:19 +02:00
By default, hyperfine displays wall-clock time and memory usage
(`time_wall_clock,memory_peak_resident` ). Use `--metrics` with a
comma-separated list to select a different set of metrics. Each
metric can have an optional unit after it:
2022-03-05 12:52:02 +01:00
2026-10-06 15:50:19 +02:00
```sh
hyperfine \
--metrics memory_peak_resident:MiB,time_wall_clock:ms,instructions \
'./baseline' './candidate'
```
2022-03-05 12:52:02 +01:00
2026-10-06 15:50:19 +02:00
The following metrics are available:
2026-10-05 16:10:08 +02:00
2026-10-05 21:11:44 +02:00
- **`time_wall_clock` **: Time from start to finish, including time spent waiting, in seconds.
2026-10-05 15:32:27 +02:00
2026-10-06 15:50:19 +02:00
- **`time_user` **: CPU time spent executing application and library code in user mode,
summed across threads, in seconds.
2026-10-05 15:32:27 +02:00
2026-10-05 21:11:44 +02:00
- Linux/macOS: Includes child-process time when parents wait for their children to finish.
- Windows: Includes the command and its child processes.
2026-10-06 15:50:19 +02:00
- **`time_system` **: CPU time spent executing kernel code on the program's behalf, for example
2026-10-05 21:11:44 +02:00
to read files, summed across threads, in seconds.
- Linux/macOS: Includes child-process time when parents wait for their children to finish.
- Windows: Includes the command and its child processes.
2026-10-06 15:50:19 +02:00
- **`time_cpu` **: Total CPU time, calculated as `time_user + time_system` for each run, in seconds.
It excludes time spent sleeping or waiting without executing. CPU time is summed across
threads, so it can exceed wall-clock time: four threads running on four cores for one second
can consume roughly four CPU-seconds.
2026-10-05 21:11:44 +02:00
- **`memory_peak_resident` **: Peak memory held in physical RAM, in bytes.
- Linux/macOS: Peak resident set size (RSS). This is the largest per-process peak among the
command and child processes (whose usage is collected when their parents wait for them),
2026-10-06 13:07:15 +02:00
*not the simultaneous total memory of the full process tree* . On Linux, measuring commands
with a very small peak RSS (below the peak inherited from hyperfine at startup, which can
be a few MiB) will currently result in that inherited value being reported instead.
2026-10-05 21:11:44 +02:00
- Windows: Currently not supported.
2026-10-05 15:32:27 +02:00
2026-10-06 08:59:40 +02:00
- **`cpu_cycles` **: CPU cycles consumed.
- Linux: Includes threads and child processes, but excludes kernel and hypervisor execution.
- macOS: Includes the process's threads and kernel execution, but excludes child processes.
- Windows: Currently not supported.
- **`instructions` **: Completed CPU instructions.
- Linux/macOS: Same scope as `cpu_cycles` .
- Windows: Currently not supported.
- **`cache_references` **: Cache accesses counted by the CPU's generic cache event.
- Linux: Same scope as `cpu_cycles` . Cache-event definitions depend on the CPU.
- macOS/Windows: Currently not supported.
- **`cache_misses` **: Cache misses.
- Linux: Same scope as `cpu_cycles` . Cache-event definitions depend on the CPU.
- macOS/Windows: Currently not supported.
- **`branch_misses` **: Mispredicted branches.
- Linux: Same scope as `cpu_cycles` .
- macOS/Windows: Currently not supported.
2026-10-06 15:55:32 +02:00
Note that hardware counters are not available when a shell is enabled (`--shell=..` ).
2026-10-06 15:50:19 +02:00
Time measurements support units `ns` , `us` , `ms` , `s` , `min` , and `h` . Memory measurements
support `B` , `kB` , `MB` , `GB` , `TB` , `KiB` , `MiB` , `GiB` , and `TiB` . Hardware counters
support `count` (1), `k` (thousand), `M` (million), and `B` (billion).
You can also use a preset to select a group of metrics:
| Preset | Metrics |
|:---|:---|
| `--metrics=default` | `time_wall_clock,memory_peak_resident` |
| `--metrics=time` | `time_wall_clock,time_cpu,time_user,time_system` |
| `--metrics=all` | All available metrics |
### Exporting results
2026-10-07 21:17:25 +02:00
Hyperfine can export results to CSV, JSON, Markdown, AsciiDoc, and org-mode. CSV exports all
selected metrics, while Markdown, AsciiDoc, and org-mode contain only the primary metric,
which is the first metric selected by `--metrics` .
2026-10-06 15:50:19 +02:00
#### Markdown
You can use the `--export-markdown <file>` option to create tables like the following:
| Command | Mean Wall Time [s] | Change | Factor |
|:---|---:|---:|:---|
| `find . -iregex '.*[0-9]\.jpg$'` | 2.275 ± 0.046 | | |
| `find . -iname '*[0-9].jpg'` | 1.427 ± 0.026 | -37.3% | (1.6x faster) |
| `fd -HI '.*[0-9]\.jpg$'` | 0.232 ± 0.002 | -89.8% | (9.8x faster) |
#### JSON
The JSON export includes all available metrics listed in [Choosing metrics and units ](#choosing-metrics-and-units )
for each measured run (excluding warmup runs).
2026-10-06 08:59:40 +02:00
2022-03-05 12:52:02 +01:00
The JSON output is useful if you want to analyze the benchmark results in more detail. The
[`scripts/` ](https://github.com/sharkdp/hyperfine/tree/master/scripts ) folder includes a lot
of helpful Python programs to further analyze benchmark results and create helpful
2022-05-19 19:19:46 +02:00
visualizations, like a histogram of runtimes or a whisker plot to compare
2026-10-07 11:24:14 +02:00
multiple benchmarks.
For example, these two commands create the following plots:
```bash
uvx --from 'git+https://github.com/sharkdp/hyperfine' \
plot_histogram results.json
uvx --from 'git+https://github.com/sharkdp/hyperfine' \
plot_whisker results.json
```
2022-03-05 12:52:02 +01:00
2022-03-05 13:07:28 +01:00
|  |  |
|---:|---:|
2022-03-05 13:02:40 +01:00
2026-10-07 21:17:25 +02:00
#### CSV
Use `--export-csv <file>` to export one row per command. Each metric selected by `--metrics`
contributes a group of columns, in selection order: `<metric>_unit` , `<metric>_mean` ,
`<metric>_stddev` , `<metric>_median` , `<metric>_min` , and `<metric>_max` .
CSV uses explicitly selected units, or base units (seconds, bytes, or counts) when omitted.
2022-03-05 13:11:50 +01:00
### Detailed benchmark flowchart
2026-10-06 15:50:19 +02:00
The following chart explains the execution order of various benchmark runs when using options
2022-03-07 08:49:33 +01:00
like `--warmup` , `--prepare <cmd>` , `--setup <cmd>` or `--cleanup <cmd>` :
2022-03-05 13:11:50 +01:00

2018-01-13 21:07:28 +01:00
## Installation
2024-11-11 22:41:35 +01:00
[](https://repology.org/project/hyperfine/versions)
2020-06-01 10:14:03 +02:00
2018-03-24 22:06:03 +01:00
### On Ubuntu
2018-01-20 14:22:26 +01:00
2025-05-15 12:16:58 +02:00
On Ubuntu, hyperfine can be installed [from the official repositories ](https://launchpad.net/ubuntu/+source/rust-hyperfine ):
```
apt install hyperfine
```
Alternatively, for the latest version, you can download the appropriate `.deb` package from the [Release page ](https://github.com/sharkdp/hyperfine/releases ) and install it via `dpkg` :
2018-01-20 14:22:26 +01:00
```
2026-10-05 14:55:32 +02:00
wget https://github.com/sharkdp/hyperfine/releases/download/v1.21.0/hyperfine_1.21.0_amd64.deb
sudo dpkg -i hyperfine_1.21.0_amd64.deb
2018-01-20 14:22:26 +01:00
```
2019-07-21 11:01:05 +02:00
### On Fedora
On Fedora, hyperfine can be installed from the official repositories:
```sh
dnf install hyperfine
```
2019-06-10 19:45:48 -04:00
### On Alpine Linux
On Alpine Linux, hyperfine can be installed [from the official repositories ](https://pkgs.alpinelinux.org/packages?name=hyperfine ):
```
apk add hyperfine
```
2018-03-24 22:06:03 +01:00
### On Arch Linux
2024-04-04 05:19:42 +00:00
On Arch Linux, hyperfine can be installed [from the official repositories ](https://archlinux.org/packages/extra/x86_64/hyperfine/ ):
2018-03-24 22:06:03 +01:00
```
2019-08-01 07:23:07 +02:00
pacman -S hyperfine
2018-03-24 22:06:03 +01:00
```
2022-12-02 16:18:26 +00:00
### On Debian Linux
2025-10-09 17:19:17 +02:00
On Debian Linux, hyperfine can be installed [from the official repositories ](https://packages.debian.org/hyperfine ):
2022-12-02 16:18:26 +00:00
```
apt install hyperfine
```
2024-04-07 10:34:11 +02:00
### On Exherbo Linux
2024-07-09 09:25:25 +02:00
On Exherbo Linux, hyperfine can be installed [from the rust repositories ](https://gitlab.exherbo.org/exherbo/rust/-/tree/master/packages/sys-apps/hyperfine ):
2024-04-07 10:34:11 +02:00
```
cave resolve -x repository/rust
cave resolve -x hyperfine
```
2019-10-30 01:23:46 +01:00
### On NixOS
On NixOS, hyperfine can be installed [from the official repositories ](https://nixos.org/nixos/packages.html?query=hyperfine ):
```
nix-env -i hyperfine
```
2024-06-12 15:06:42 +02:00
### On Flox
On Flox, hyperfine can be installed as follows.
```
flox install hyperfine
```
Hyperfine's version in Flox follows that of Nix.
2023-10-18 22:57:57 +09:00
### On openSUSE
On openSUSE, hyperfine can be installed [from the official repositories ](https://software.opensuse.org/package/hyperfine ):
```
zypper install hyperfine
```
2018-03-24 22:06:03 +01:00
### On Void Linux
2018-01-30 18:55:26 -05:00
Hyperfine can be installed via xbps
```
xbps-install -S hyperfine
```
2018-01-20 14:22:26 +01:00
2019-06-08 14:36:45 +02:00
### On macOS
Hyperfine can be installed via [Homebrew ](https://brew.sh ):
```
brew install hyperfine
```
2020-04-01 16:19:47 -04:00
Or you can install using [MacPorts ](https://www.macports.org ):
```
sudo port selfupdate
sudo port install hyperfine
```
2019-08-26 11:46:53 +02:00
### On FreeBSD
Hyperfine can be installed via pkg:
```
pkg install hyperfine
```
2020-05-19 00:14:14 +02:00
### On OpenBSD
```
doas pkg_add hyperfine
```
2023-03-01 09:22:35 +08:00
### On Windows
Hyperfine can be installed via [Chocolatey ](https://community.chocolatey.org/packages/hyperfine ), [Scoop ](https://scoop.sh/#/apps?q=hyperfine&s=0&d=1&o=true&id=8f7c10f75ecf5f9e42a862c615257328e2f70f61 ), or [Winget ](https://github.com/microsoft/winget-pkgs/tree/master/manifests/s/sharkdp/hyperfine ):
```
choco install hyperfine
```
```
scoop install hyperfine
```
```
winget install hyperfine
```
2019-06-08 08:59:52 +02:00
### With conda
2019-06-07 23:54:44 +02:00
2019-06-08 08:59:52 +02:00
Hyperfine can be installed via [`conda` ](https://conda.io/en/latest/ ) from the [`conda-forge` ](https://anaconda.org/conda-forge/hyperfine ) channel:
2019-06-07 23:54:44 +02:00
```
conda install -c conda-forge hyperfine
```
2018-03-24 22:06:03 +01:00
### With cargo (Linux, macOS, Windows)
2022-02-03 21:44:23 +01:00
Hyperfine can be installed from source via [cargo ](https://doc.rust-lang.org/cargo/ ):
2018-03-24 22:06:03 +01:00
```
2023-01-15 14:48:02 +01:00
cargo install --locked hyperfine
2018-03-24 22:06:03 +01:00
```
2026-10-02 11:05:02 +02:00
Make sure that you use Rust 1.97 or newer.
2018-07-18 18:11:05 +02:00
2018-09-28 22:02:24 +02:00
### From binaries (Linux, macOS, Windows)
2018-03-24 22:06:03 +01:00
Download the corresponding archive from the [Release page ](https://github.com/sharkdp/hyperfine/releases ).
2019-06-08 14:29:07 +02:00
## Alternative tools
2023-02-20 17:39:07 +01:00
Hyperfine is inspired by [bench ](https://github.com/Gabriella439/bench ).
2020-10-16 23:57:21 +02:00
2020-01-04 11:46:25 +01:00
## Integration with other tools
[Chronologer ](https://github.com/dandavison/chronologer ) is a tool that uses `hyperfine` to
visualize changes in benchmark timings across your Git history.
2023-12-05 11:43:31 -05:00
[Bencher ](https://github.com/bencherdev/bencher ) is a continuous benchmarking tool that supports `hyperfine` to
track benchmarks and catch performance regressions in CI.
2025-01-10 08:51:13 +01:00
Drop hyperfine JSON outputs onto the [Venz ](https://try.venz.dev ) chart to visualize the results,
and manage hyperfine configurations.
2020-01-04 11:46:25 +01:00
Make sure to check out the [`scripts` folder ](https://github.com/sharkdp/hyperfine/tree/master/scripts )
in this repository for a set of tools to work with `hyperfine` benchmark results.
2019-06-08 14:29:07 +02:00
2018-01-13 20:27:24 +01:00
## Origin of the name
The name *hyperfine* was chosen in reference to the hyperfine levels of caesium 133 which play a crucial role in the
2018-09-04 19:44:59 +10:00
[definition of our base unit of time ](https://en.wikipedia.org/wiki/Second#History_of_definition )
2018-01-13 20:27:24 +01:00
— the second.
2020-01-20 00:16:50 +09:00
2022-09-14 11:17:30 +10:00
## Citing hyperfine
2026-10-02 11:45:20 +02:00
Thank you for considering citing hyperfine in your research work. Please see the information
2022-10-13 22:28:08 +02:00
in the sidebar on how to properly cite hyperfine.
2022-09-14 11:17:30 +10:00
2020-01-20 00:16:50 +09:00
## License
2021-08-22 17:17:48 +02:00
`hyperfine` is dual-licensed under the terms of the MIT License and the Apache License 2.0.
2020-01-20 00:16:50 +09:00
2021-08-22 17:17:48 +02:00
See the [LICENSE-APACHE ](LICENSE-APACHE ) and [LICENSE-MIT ](LICENSE-MIT ) files for details.