Files
hyperfine/README.md
T

239 lines
7.4 KiB
Markdown
Raw Normal View History

2018-01-13 20:27:24 +01:00
# hyperfine
2021-07-27 09:27:22 +02:00
[![CICD](https://github.com/sharkdp/hyperfine/actions/workflows/CICD.yml/badge.svg)](https://github.com/sharkdp/hyperfine/actions/workflows/CICD.yml)
2018-01-18 19:19:13 +01:00
[![Version info](https://img.shields.io/crates/v/hyperfine.svg)](https://crates.io/crates/hyperfine)
2018-10-19 21:35:21 +02:00
[中文](https://github.com/chinanf-boy/hyperfine-zh)
2018-01-13 20:27:24 +01:00
2019-06-08 14:29:07 +02:00
A command-line benchmarking tool.
2018-01-13 20:27:24 +01:00
2018-01-18 18:13:12 +01:00
**Demo**: Benchmarking [`fd`](https://github.com/sharkdp/fd) and
[`find`](https://www.gnu.org/software/findutils/):
2018-01-14 22:19:52 +01:00
2020-06-07 23:09:27 +02:00
![hyperfine](https://i.imgur.com/z19OYxE.gif)
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.
* Support for arbitrary shell commands.
* Constant feedback about the benchmark progress and current estimates.
* Warmup runs can be executed before the actual benchmark.
* Cache-clearing commands can be set up before each timing 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
### Basic benchmark
2018-01-18 18:13:12 +01:00
To run a benchmark, you can simply call `hyperfine <command>...`. The argument(s) can be any
shell command. For example:
2018-01-16 22:03:50 +01:00
``` bash
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,
it will perform *at least* 10 benchmarking runs. To change this, you can use the `-m`/`--min-runs`
option:
2018-01-16 22:03:50 +01:00
``` bash
2018-01-24 08:32:11 +01:00
hyperfine --min-runs 5 'sleep 0.2' 'sleep 3.2'
2018-01-16 22:03:50 +01:00
```
2019-10-13 16:24:46 +02:00
### Warmup runs and preparation commands
2018-01-16 22:03:50 +01:00
2018-01-18 18:13:12 +01:00
If the program execution time is limited by disk I/O, the benchmarking results can be heavily
2018-01-30 22:33:00 +01:00
influenced by disk caches and whether they are cold or warm.
2018-01-16 22:03:50 +01:00
2018-01-18 18:13:12 +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:
2018-01-16 22:03:50 +01:00
``` bash
2018-01-24 08:32:11 +01:00
hyperfine --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`
option to run a special command before *each* timing run. For example, to clear harddisk caches
on Linux, you can run
2018-01-16 22:03:50 +01:00
``` bash
sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
```
2018-01-22 22:21:48 +00: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:
2018-01-16 22:03:50 +01:00
``` bash
2018-01-18 18:13:12 +01:00
hyperfine --prepare 'sync; echo 3 | sudo tee /proc/sys/vm/drop_caches' 'grep -R TODO *'
2018-01-16 22:03:50 +01:00
```
### Parameterized benchmarks
If you want to run a benchmark where only a single parameter is varied (say, the number of
threads), you can use the `-P`/`--parameter-scan` option and call:
``` bash
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:
``` bash
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`.
2020-10-26 15:37:01 -03:00
### Shell functions and aliases
If you are using bash, you can export shell functions to directly benchmark them with hyperfine:
```
$ my_function() { sleep 1; }
$ export -f my_function
$ hyperfine my_function
```
If you are using a different shell, or if you want to benchmark shell aliases, you may try to put
them in a separate file:
```bash
echo 'my_function() { sleep 1 }' > /tmp/my_function.sh
echo 'alias my_alias="sleep 1"' > /tmp/my_alias.sh
hyperfine 'source /tmp/my_function.sh; eval my_function'
hyperfine 'source /tmp/my_alias.sh; eval my_alias'
```
### Export results
Hyperfine has multiple options for exporting benchmark results: CSV, JSON, Markdown (see `--help`
text for details). To export results to Markdown, for example, you can use the `--export-markdown`
option that will create tables like this:
2019-06-08 14:36:45 +02:00
| Command | Mean [s] | Min [s] | Max [s] | Relative |
|:---|---:|---:|---:|---:|
2019-10-13 16:03:04 +02:00
| `find . -iregex '.*[0-9]\.jpg$'` | 2.275 ± 0.046 | 2.243 | 2.397 | 9.79 ± 0.22 |
| `find . -iname '*[0-9].jpg'` | 1.427 ± 0.026 | 1.405 | 1.468 | 6.14 ± 0.13 |
| `fd -HI '.*[0-9]\.jpg$'` | 0.232 ± 0.002 | 0.230 | 0.236 | 1.00 |
2018-12-12 20:37:51 +01:00
The JSON output is useful if you want to analyze the benchmark results in more detail. See the
[`scripts/`](https://github.com/sharkdp/hyperfine/tree/master/scripts) folder for some examples.
2018-01-13 21:07:28 +01:00
## Installation
2020-06-01 10:14:03 +02:00
[![Packaging status](https://repology.org/badge/vertical-allrepos/hyperfine.svg)](https://repology.org/project/hyperfine/versions)
2018-03-24 22:06:03 +01:00
### On Ubuntu
2018-01-20 14:22:26 +01:00
Download the appropriate `.deb` package from the [Release page](https://github.com/sharkdp/hyperfine/releases)
and install it via `dpkg`:
```
2021-10-17 19:32:55 +02:00
wget https://github.com/sharkdp/hyperfine/releases/download/v1.12.0/hyperfine_1.12.0_amd64.deb
sudo dpkg -i hyperfine_1.12.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
On Arch Linux, hyperfine can be installed [from the official repositories](https://www.archlinux.org/packages/community/x86_64/hyperfine/):
2018-03-24 22:06:03 +01:00
```
pacman -S hyperfine
2018-03-24 22:06:03 +01:00
```
2021-10-03 15:52:29 +03:00
### On Funtoo Linux
On Funtoo Linux, hyperfine can be installed [from core-kit](https://github.com/funtoo/core-kit/tree/1.4-release/app-benchmarks/hyperfine):
```
emerge app-benchmarks/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
```
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
```
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
```
2019-06-08 08:59:52 +02:00
### With conda
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:
```
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
```
cargo install hyperfine
```
2022-02-05 22:14:06 +01:00
Make sure that you use Rust 1.57 or higher.
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
2020-01-04 11:46:25 +01:00
Hyperfine is inspired by [bench](https://github.com/Gabriel439/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.
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
## 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.