Files
hyperfine/src/app.rs
T

260 lines
11 KiB
Rust
Raw Normal View History

2021-08-24 21:33:48 +02:00
use std::ffi::OsString;
2018-03-24 18:30:52 -04:00
use atty::Stream;
2019-05-07 11:55:38 +02:00
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
2018-03-24 18:30:52 -04:00
pub fn get_arg_matches<I, T>(args: I) -> ArgMatches<'static>
2018-03-24 18:30:52 -04:00
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
2018-03-24 18:30:52 -04:00
{
let app = build_app();
app.get_matches_from(args)
}
/// Build the clap app for parsing command line arguments
fn build_app() -> App<'static, 'static> {
let clap_color_setting = if atty::is(Stream::Stdout) {
AppSettings::ColoredHelp
} else {
AppSettings::ColorNever
};
App::new("hyperfine")
.version(crate_version!())
.setting(clap_color_setting)
.setting(AppSettings::DeriveDisplayOrder)
.setting(AppSettings::UnifiedHelpMessage)
.setting(AppSettings::NextLineHelp)
.setting(AppSettings::HidePossibleValuesInHelp)
.max_term_width(90)
.about("A command-line benchmarking tool.")
.arg(
Arg::with_name("command")
.help("Command to benchmark")
.required(true)
.multiple(true)
.empty_values(false),
)
.arg(
Arg::with_name("warmup")
.long("warmup")
.short("w")
.takes_value(true)
.value_name("NUM")
.help(
"Perform NUM warmup runs before the actual benchmark. This can be used \
to fill (disk) caches for I/O-heavy programs.",
),
)
.arg(
Arg::with_name("min-runs")
.long("min-runs")
.short("m")
.takes_value(true)
.value_name("NUM")
.help("Perform at least NUM runs for each command (default: 10)."),
)
.arg(
Arg::with_name("max-runs")
.long("max-runs")
.short("M")
.takes_value(true)
.value_name("NUM")
2019-10-13 16:24:29 +02:00
.help("Perform at most NUM runs for each command. By default, there is no limit."),
)
.arg(
Arg::with_name("runs")
.long("runs")
2018-09-09 21:52:58 +01:00
.conflicts_with_all(&["max-runs", "min-runs"])
.short("r")
.takes_value(true)
.value_name("NUM")
2019-10-13 16:24:29 +02:00
.help("Perform exactly NUM runs for each command. If this option is not specified, \
hyperfine automatically determines the number of runs."),
)
.arg(
Arg::with_name("setup")
.long("setup")
.short("s")
.takes_value(true)
.number_of_values(1)
.value_name("CMD")
.help(
"Execute CMD before each set of timing runs. This is useful for \
compiling your software with the provided parameters, or to do any \
other work that should happen once before a series of benchmark runs,\
not every time as would happen with the --prepare option."
),
)
2018-03-24 18:30:52 -04:00
.arg(
Arg::with_name("prepare")
.long("prepare")
.short("p")
.takes_value(true)
2019-10-02 18:56:55 +05:45
.multiple(true)
.number_of_values(1)
2018-03-24 18:30:52 -04:00
.value_name("CMD")
.help(
2019-10-13 18:10:53 +05:45
"Execute CMD before each timing run. This is useful for \
2019-10-13 14:47:18 +02:00
clearing disk caches, for example.\nThe --prepare option can \
2019-10-13 18:10:53 +05:45
be specified once for all commands or multiple times, once for \
each command. In the latter case, each preparation command will \
be run prior to the corresponding benchmark command.",
2018-03-24 18:30:52 -04:00
),
)
.arg(
Arg::with_name("cleanup")
.long("cleanup")
.short("c")
.takes_value(true)
.value_name("CMD")
.help(
2019-01-14 08:33:38 -08:00
"Execute CMD after the completion of all benchmarking \
runs for each individual command to be benchmarked. \
This is useful if the commands to be benchmarked produce \
artifacts that need to be cleaned up."
),
)
2018-03-24 18:30:52 -04:00
.arg(
Arg::with_name("parameter-scan")
.long("parameter-scan")
.short("P")
.takes_value(true)
.allow_hyphen_values(true)
.value_names(&["VAR", "MIN", "MAX"])
2018-03-24 18:30:52 -04:00
.help(
"Perform benchmark runs for each value in the range MIN..MAX. Replaces the \
2019-10-13 16:24:29 +02:00
string '{VAR}' in each command by the current parameter value.\n\n \
Example: hyperfine -P threads 1 8 'make -j {threads}'\n\n\
2021-10-10 19:26:13 +00:00
This performs benchmarks for 'make -j 1', 'make -j 2', …, 'make -j 8'.\n\n\
To have the value increase following different patterns, use shell arithmetics.\n\n \
Example: hyperfine -P size 0 3 'sleep $((2**{size}))'\n\n\
This performs benchmarks with power of 2 increases: 'sleep 1', 'sleep 2', 'sleep 4', …\n\
The exact syntax may vary depending on your shell and OS."
),
2018-03-24 18:30:52 -04:00
)
.arg(
Arg::with_name("parameter-step-size")
.long("parameter-step-size")
.short("D")
.takes_value(true)
.value_names(&["DELTA"])
.requires("parameter-scan")
.help(
2019-09-13 00:54:50 +01:00
"This argument requires --parameter-scan to be specified as well. \
2019-10-13 16:24:29 +02:00
Traverse the range MIN..MAX in steps of DELTA.\n\n \
Example: hyperfine -P delay 0.3 0.7 -D 0.2 'sleep {delay}'\n\n\
This performs benchmarks for 'sleep 0.3', 'sleep 0.5' and 'sleep 0.7'.",
),
)
.arg(
Arg::with_name("parameter-list")
.long("parameter-list")
.short("L")
.takes_value(true)
.multiple(true)
.allow_hyphen_values(true)
.value_names(&["VAR", "VALUES"])
.conflicts_with_all(&["parameter-scan", "parameter-step-size"])
.help(
2020-05-22 21:35:37 +02:00
"Perform benchmark runs for each value in the comma-separated list VALUES. \
Replaces the string '{VAR}' in each command by the current parameter value\
2019-10-20 10:02:05 +02:00
.\n\nExample: hyperfine -L compiler gcc,clang '{compiler} -O2 main.cpp'\n\n\
2020-10-17 00:07:06 +02:00
This performs benchmarks for 'gcc -O2 main.cpp' and 'clang -O2 main.cpp'.\n\n\
The option can be specified multiple times to run benchmarks for all \
possible parameter combinations.\n"
),
)
2018-03-24 18:30:52 -04:00
.arg(
Arg::with_name("style")
.long("style")
.takes_value(true)
.value_name("TYPE")
.possible_values(&["auto", "basic", "full", "nocolor", "color", "none"])
2018-03-24 18:30:52 -04:00
.help(
"Set output style type (default: auto). Set this to 'basic' to disable output \
coloring and interactive elements. Set it to 'full' to enable all effects \
even if no interactive terminal was detected. Set this to 'nocolor' to \
2019-01-02 17:13:05 +01:00
keep the interactive output without any colors. Set this to 'color' to keep \
the colors without any interactive output. Set this to 'none' to disable all \
the output of the tool.",
2018-03-24 18:30:52 -04:00
),
)
2018-10-30 19:30:17 -07:00
.arg(
Arg::with_name("shell")
.long("shell")
.short("S")
.takes_value(true)
.value_name("SHELL")
.overrides_with("shell")
2019-10-13 16:24:29 +02:00
.help("Set the shell to use for executing benchmarked commands."),
2018-10-30 19:30:17 -07:00
)
2018-03-24 18:30:52 -04:00
.arg(
Arg::with_name("ignore-failure")
.long("ignore-failure")
.short("i")
2019-10-13 16:24:29 +02:00
.help("Ignore non-zero exit codes of the benchmarked programs."),
2018-03-24 18:30:52 -04:00
)
.arg(
Arg::with_name("time-unit")
.long("time-unit")
.short("u")
.takes_value(true)
.value_name("UNIT")
.possible_values(&["millisecond", "second"])
2019-10-13 16:24:29 +02:00
.help("Set the time unit to be used. Possible values: millisecond, second."),
)
2019-01-29 18:02:19 -05:00
.arg(
Arg::with_name("export-asciidoc")
.long("export-asciidoc")
.takes_value(true)
.value_name("FILE")
2020-05-22 21:36:51 +02:00
.help("Export the timing summary statistics as an AsciiDoc table to the given FILE."),
2019-01-29 18:02:19 -05:00
)
2018-03-24 18:30:52 -04:00
.arg(
Arg::with_name("export-csv")
.long("export-csv")
.takes_value(true)
.value_name("FILE")
2019-10-13 16:24:29 +02:00
.help("Export the timing summary statistics as CSV to the given FILE. If you need \
the timing results for each individual run, use the JSON export format."),
2018-03-24 18:30:52 -04:00
)
.arg(
Arg::with_name("export-json")
.long("export-json")
.takes_value(true)
.value_name("FILE")
.help("Export the timing summary statistics and timings of individual runs as JSON to the given FILE."),
2018-03-24 18:30:52 -04:00
)
.arg(
Arg::with_name("export-markdown")
.long("export-markdown")
.takes_value(true)
.value_name("FILE")
.help("Export the timing summary statistics as a Markdown table to the given FILE."),
2018-03-24 18:30:52 -04:00
)
.arg(
2018-05-21 21:04:30 +02:00
Arg::with_name("show-output")
.long("show-output")
.conflicts_with("style")
2018-05-22 22:57:51 +02:00
.help(
"Print the stdout and stderr of the benchmark instead of suppressing it. \
This will increase the time it takes for benchmarks to run, \
so it should only be used for debugging purposes or \
when trying to benchmark output speed.",
),
)
.arg(
Arg::with_name("command-name")
2020-10-15 22:11:38 +02:00
.long("command-name")
.short("n")
.takes_value(true)
.multiple(true)
.number_of_values(1)
.value_name("NAME")
.help("Give a meaningful name to a command"),
)
2018-03-24 18:30:52 -04:00
.help_message("Print this help message.")
.version_message("Show version information.")
}