HYPERFINE(1)
π HYPERFINE(1) β NAME π
okay so first things first, bestie: we're in the General Commands Manual, section 1, and the star of the show is hyperfine β a command-line benchmarking tool. that's it, that's the whole vibe. it times your commands so you can find out what's actually fast and what's giving sluggish. π
β¨ SYNOPSIS β¨
the way you call it is literally this, copy-paste energy:
hyperfine [-hVNS] [--ignore-failure[=MODE]] [--warmup NUM] [--min-runs
NUM] [--max-runs NUM] [--runs NUM] [--setup CMD] [--prepare CMD]
[--conclude CMD] [--cleanup CMD] [--parameter-scan VAR MIN MAX]
[--parameter-step-size DELTA] [--parameter-list VAR VALUES] [--shell
SHELL] [--style TYPE] [--metrics METRIC[:UNIT],...|default|time|all]
[--export-asciidoc FILE] [--export-csv FILE] [--export-json FILE]
[--export-markdown FILE] [--export-orgmode FILE] [--output WHERE]
[--input WHERE] [--command-name NAME] [COMMAND...]
like yes, that's a lot of brackets, but trust β every single one of those is a real option and we're gonna get to all of them. no skips, no summaries, we do the whole list. π
π¦ DESCRIPTION π¦
so hyperfine is a command-line benchmarking tool, and here's the lineup of what it includes (this is the official feature roster, i'm just delivering it with β¨flavorβ¨):
- Statistical analysis across multiple runs β it doesn't just run your command once and call it a day, it does actual stats across multiple runs, so one weird fluke doesn't tank your whole conclusion. π
- Support for arbitrary shell commands β honestly any arbitrary shell command you wanna throw at it? it'll benchmark that. no cap.
- Constant feedback about the benchmark progress and current estimates β it keeps you posted the whole time with feedback on the benchmark progress and its current estimates, so you're never just staring at a blinking cursor wondering if it died. π
- Warmup runs can be executed before the actual benchmark β you can fire off warmup runs before the actual benchmark even starts, so your first-run cold-cache chaos doesn't mess up the numbers. π₯
- Cache-clearing commands can be set up before each benchmark run β you can set up cache-clearing commands to run before each benchmark run. yes, each one. iconic consistency behavior. π§
- Statistical outlier detection to detect interference from other programs and caching effects β it does statistical outlier detection specifically to detect interference from other programs and caching effects. like it's out here catching the haters (background processes) for you. π
- Export results to various formats: CSV, JSON, Markdown, AsciiDoc β results can be exported to various formats:
CSV,JSON,Markdown, andAsciiDoc. take your receipts anywhere. π - Parameterized benchmarks (e.g. vary the number of threads) β parameterized benchmarks are a whole thing, e.g. vary the number of threads and watch the numbers do their little dance. π₯
that's the description, bestie β the flags and options are the next bit, and there are so many of them, so hydrate first. π
β¨ OPTIONS β¨
okay bestie, this is the part where hyperfine shows you everything it can do, and honestly? it's a lot. but don't panic β we got this π
-w, --warmup NUMβ doesNUMwarmup runs before the actual benchmark even starts. literally just to warm things up first, no cap. super useful for filling up (disk) caches when you're benchmarking I/O-heavy programs π«Ά-m, --min-runs NUMβ do at leastNUMruns for each command. default:10.-M, --max-runs NUMβ do at mostNUMruns for each command. by default there's no limit at all, go off queen π-r, --runs NUMβ do exactlyNUMruns for each command. if you don't specify this one, hyperfine just figures out the number of runs on its own (main character energy, it just knows).-s, --setup CMD...β runCMDonce before each set of benchmark runs. perfect for compiling your software with the provided parameters, or literally any other work that should happen once before a whole series of runs β not every single time, which is what--preparewould do. big difference, iykyk.-p, --prepare CMD...β runCMDbefore each benchmark run. great for clearing disk caches, for example. you can specify--prepareonce for all commands, or multiple times β one for each command. in that multiple-times case, each preparation command runs right before its corresponding benchmark command β¨-C, --conclude CMD...β runCMDafter each benchmark run. also great for clearing disk caches, for example. same deal as--prepare: once for all commands, or multiple times, once for each command. in the multi case, each conclusion command runs after its corresponding benchmark command π-c, --cleanup CMD...β runCMDafter all the benchmarking runs for each individual command are done. this is your girl if the benchmarked commands produce artifacts that need cleaning up. it only runs once per series of benchmark runs β versus--conclude, which runs after every single run. important distinction bestie π¦-P, --parameter-scan VAR MIN MAXβ do benchmark runs for every value in the rangeMIN..MAX, and replace the string'{VAR}'in each command with the current parameter value. iconic.
example:
hyperfine --prepare 'make clean' -P threads 1 8 'make -j {threads}'
this benchmarks 'make -j 1', 'make -j 2', ..., all the way to 'make -j 8'.
and if you want the value to go up in a different pattern, just use shell arithmetic:
hyperfine --shell=bash -P size 0 3 'sleep $((2**{size}))'
this one does power-of-2 increases: 'sleep 1', 'sleep 2', 'sleep 4', ...
heads up: the exact syntax may vary depending on your shell and OS πΈ
-D, --parameter-step-size DELTAβ this one requires--parameter-scanto be specified too (it's a package deal, fr). it walks the rangeMIN..MAXin steps ofDELTA, andDELTAmust be positive.
example:
hyperfine -P delay 0.3 0.7 -D 0.2 'sleep {delay}'
that benchmarks 'sleep 0.3', 'sleep 0.5' and 'sleep 0.7'. slay.
-L, --parameter-list VAR VALUESβ do benchmark runs for each value in the comma-separated list ofVALUES, replacing the string'{VAR}'in each command with the current parameter value π
example:
hyperfine -L compiler g++,clang++ '{compiler} -O2 main.cpp'
this benchmarks 'g++ -O2 main.cpp' and 'clang++ -O2 main.cpp'.
and you can specify this option multiple times to run benchmarks for all possible parameter combinations β yes, every combo, she's thorough π
--env ASSIGNMENTSβ sets environment variables for the benchmark commands and their respective setup, prepare, conclude, and cleanup commands. the assignments are space-separated and support shell-style quoting, but no shell expansion, e.g.--env 'OMP_NUM_THREADS=8 CFLAGS="-O3 -march=native"'. specify it once for all commands, or once per benchmark command, just like--prepare. use an empty string for no overrides. values can also contain parameter placeholders π§
for example, hyperfine -P threads 1 8 --env 'OMP_NUM_THREADS={threads}' 'my_command' benchmarks 'my_command' with OMP_NUM_THREADS ranging from 1 to 8. obsessed.
--shell SHELLβ sets the shell used to execute the benchmarked commands, including the warmup runs (default:none). it can be the name or the path to the shell executable, or even a full command line like"bash --norc". you can also set it to"default"to explicitly select the platform shell (shon Unix,cmd.exeon Windows). and finally, you can set it to"none"to disable the shell entirely β in that case the benchmarked commands are executed directly. they can still have arguments, but more complex stuff like"sleep 0.1; sleep 0.2"is not possible without a shell, no cap.
also important: setup, prepare, conclude, and cleanup commands always use a shell β either the selected shell, or the platform shell when this option is omitted or set to "none". so don't get it twisted π
-Sβ an alias for'--shell=default'(shon Unix,cmd.exeon Windows). short and sweet.-Nβ an alias for'--shell=none'. equally short, equally sweet.-i, --ignore-failure[=MODE]β ignore failures of the benchmarked programs. without a value, or withall-non-zero, all non-zero exit codes get ignored. alternatively, hand it a comma-separated list of exit codes to ignore, like--ignore-failure=1,2. an explicit value must be attached to the option with an equals sign β don't forget the=, bestie β¨--style TYPEβ sets the output styleTYPE(default:auto). the tea:'basic'β disables output coloring and interactive elements'full'β enables all the effects even if no interactive terminal was detected'nocolor'β keeps the interactive output but with zero colors'color'β keeps the colors but with no interactive output'none'β disables all the output of the tool π«Ά
--metrics METRIC[:UNIT],...|default|time|allβ selects the metrics to measure, in order, with an optional unit for each. default:time_wall_clock,memory_peak_resident, ortime_wall_clockon Windows where peak resident memory is not yet supported π
use default for the platform defaults, time for time_wall_clock,time_cpu,time_user,time_system, or all for all available metrics in the order listed below.
the time metrics time_wall_clock, time_cpu, time_user, and time_system accept units ns, us, ms, s, min, and h. peak memory, memory_peak_resident, accepts B, kB, MB, GB, TB, KiB, MiB, GiB, and TiB. the counter metrics cpu_cycles, instructions, cache_references, cache_misses, and branch_misses accept count (unscaled), k (thousand), M (million), and B (billion) π
if a unit is omitted, terminal and markup output automatically pick a suitable one.
example:
hyperfine --metrics memory_peak_resident:MiB,time_wall_clock:ms,instructions:B './baseline' './candidate'
--export-asciidoc FILEβ exports the primary metric's summary statistics as an AsciiDoc table to the givenFILE. it uses the selected unit, or chooses one automatically when it's omitted π--export-csv FILEβ exports summary statistics for all selected metrics as CSV to the givenFILE, one row per command. each metric contributes columns for unit, mean, stddev, median, min, and max, prefixed with the metric name, in selection order. the command column comes first and the parameter columns come last. it uses the explicitly selected units, or base units (seconds, bytes, or unscaled counts) when omitted π¦--export-json FILEβ exports summary statistics and individual samples for all collected metrics as JSON to the givenFILE. includes the primary metric, and always uses base units (seconds, bytes, or unscaled counts), regardless of your display settings. no vibes-based units here, only facts.--export-markdown FILEβ exports the primary metric's summary statistics as a Markdown table to the givenFILE. uses its selected unit, or chooses one automatically when omitted. perfect for pasting into your README, periodt π--export-orgmode FILEβ exports the primary metric's summary statistics as an Emacs org-mode table to the givenFILE. uses its selected unit, or chooses one automatically when omitted πΈ--show-outputβ prints the stdout and stderr of the benchmark instead of suppressing it. real talk though: this increases the time it takes for benchmarks to run, so only use it for debugging purposes or when you're literally trying to benchmark output speed. it's giving chaos on purpose π--output WHEREβ controls where the output of the benchmark gets redirected. note that some programs like'grep'detect when standard output is/dev/nulland apply certain optimizations β to avoid that nonsense, consider using--output=pipeπ
WHERE can be:
nullβ redirect output to/dev/null(the default).pipeβ feed the output through a pipe before discarding it.inheritβ don't redirect the output at all (same as'--show-output').<FILE>β write the output to the given file.
this option can be specified once for all commands or multiple times, once for each command.
note: if you want to log the output of each and every iteration, you can use a shell redirection and the$HYPERFINE_ITERATIONenvironment variable (requires-S/--shell=default). iykyk β¨
--input WHEREβ controls where the input of the benchmark comes from.WHEREcan be:nullβ read from/dev/null(the default).<FILE>β read the input from the given file.
-n, --command-name NAMEβ gives a meaningfulNAMEto a command. can be specified multiple times if several commands are being benchmarked β give them all cute lil labels, they deserve it π-h, --helpβ print help.-V, --versionβ print version.
π EXAMPLES π
Okay bestie, this is the part where it all clicks. Real commands, real vibes, copy-paste energy. Let's go π
πΈ The starter pack: one basic benchmark
A basic, no-thoughts-just-vibes benchmark of find . -name todo.txt:
hyperfine 'find . -name todo.txt'
Literally the simplest thing you can do and it still slays β¨
β±οΈ Setting a minimum run count
Wanna benchmark sleep 0.2 and sleep 3.2, but with a minimum of 5 runs for each? Say less:
hyperfine --min-runs 5 'sleep 0.2' 'sleep 3.2'
Five runs minimum, no cap. The slow one is gonna have a bad time π
π₯ Warm that disk cache up first
Benchmarking grep but you want a warm disk cache? Do 3 runs up front that are not part of the measurement β a little pre-game, a little stretch before the main character moment:
hyperfine -S --warmup 3 'grep -R TODO *'
Note the -S (that's the shell-spawning flag from the OPTIONS section, iykyk) and --warmup 3 doing the unpaid rehearsal runs. Chef's kiss π«Ά
π Exporting a parameter scan to markdown
Export the results of a parameter scan benchmark straight to a markdown table, because a girl needs her data looking cute in a README:
hyperfine --export-markdown output.md --parameter-scan time 1 5 'sleep {time}'
Scan time from 1 to 5, drop it all into output.md. Iconic table behaviour, honestly π
π§ The full lifecycle demo (aka the one that explains everything)
This one demonstrates when each of --setup, --prepare, --conclude, cmd and --cleanup will run. Like a little choreographed dance, and everyone hits their mark:
hyperfine -L n 1,2 -r 2 --show-output \
--setup 'echo setup n={n}' \
--prepare 'echo prepare={n}' \
--conclude 'echo conclude={n}' \
--cleanup 'echo cleanup n={n}' \
'echo command n={n}'
Read it slowly, bestie β -L n 1,2 runs the whole thing for n=1 and n=2, -r 2 gives you 2 runs each, and --show-output lets you actually see the echoes so you can watch the order happen in real time. It's giving anatomy diagram of a benchmark ππ
π AUTHOR π
David Peter <mail@david-peter.de> β the actual legend who made this whole thing, put some respect on the name π
Source, bug tracker, and additional information can be found on GitHub: https://github.com/sharkdp/hyperfine
Go star the repo, file your bugs nicely, and remember: hyperfine(1) section 1, forever in our hearts. Now go benchmark something and slay π¦π
β signed with love, your terminal bestie, on behalf of HYPERFINE(1) π
π¦ where this page comes from
- arch rolling: hyperfine 2.0.0-1 Β· Apache-2.0 OR MIT
- nixpkgs unstable: hyperfine 2.0.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms