Files
hyperfine/src/main.rs
T

96 lines
2.6 KiB
Rust
Raw Normal View History

2018-01-13 16:50:02 +01:00
extern crate ansi_term;
2018-01-13 20:53:55 +01:00
#[macro_use]
2018-01-13 16:50:02 +01:00
extern crate clap;
2018-01-13 19:01:52 +01:00
extern crate indicatif;
2018-01-13 16:50:02 +01:00
2018-01-13 21:01:30 +01:00
use std::cmp;
2018-01-14 11:41:27 +13:00
use std::error::Error;
use std::io;
2018-01-13 16:50:02 +01:00
2018-01-14 20:14:10 +01:00
use ansi_term::Colour::Red;
2018-01-13 16:50:02 +01:00
use clap::{App, AppSettings, Arg};
2018-01-14 20:14:10 +01:00
mod hyperfine;
2018-01-14 10:48:47 +01:00
2018-01-14 20:14:10 +01:00
use hyperfine::internal::HyperfineOptions;
use hyperfine::benchmark::{mean_shell_spawning_time, run_benchmark};
2018-01-14 10:48:47 +01:00
2018-01-14 11:41:27 +13:00
/// Print error message to stderr and terminate
pub fn error(message: &str) -> ! {
2018-01-14 12:39:58 +01:00
eprintln!("{}: {}", Red.paint("Error"), message);
2018-01-14 11:41:27 +13:00
std::process::exit(1);
}
2018-01-14 12:03:34 +01:00
/// Runs the benchmark for the given commands
fn run(commands: &Vec<&str>, options: &HyperfineOptions) -> io::Result<()> {
let shell_spawning_time = mean_shell_spawning_time()?;
// Run the benchmarks
2018-01-14 13:34:22 +01:00
for (num, cmd) in commands.iter().enumerate() {
run_benchmark(num, &cmd, shell_spawning_time, &options)?;
2018-01-14 12:03:34 +01:00
}
Ok(())
}
2018-01-13 16:50:02 +01:00
fn main() {
let matches = App::new("hyperfine")
2018-01-13 20:53:55 +01:00
.version(crate_version!())
.setting(AppSettings::ColoredHelp)
.setting(AppSettings::DeriveDisplayOrder)
2018-01-13 16:50:02 +01:00
.about("A command-line benchmarking tool")
.arg(
Arg::with_name("command")
.help("Command to benchmark")
.required(true)
2018-01-14 11:41:27 +13:00
.multiple(true)
.empty_values(false),
2018-01-13 16:50:02 +01:00
)
2018-01-13 20:05:31 +01:00
.arg(
Arg::with_name("warmup")
.long("warmup")
.short("w")
.takes_value(true)
.value_name("NUM")
.help("Perform NUM warmup runs before the actual benchmark"),
)
2018-01-13 21:01:30 +01:00
.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"),
)
2018-01-14 12:39:58 +01:00
.arg(
Arg::with_name("ignore-failure")
.long("ignore-failure")
.short("i")
.help("Ignore non-zero exit codes"),
)
2018-01-13 16:50:02 +01:00
.get_matches();
2018-01-13 21:01:30 +01:00
let str_to_u64 = |n| u64::from_str_radix(n, 10).ok();
2018-01-13 19:01:52 +01:00
2018-01-13 21:01:30 +01:00
// Process command line options
let mut options = HyperfineOptions::default();
2018-01-14 12:39:58 +01:00
2018-01-14 12:22:29 +01:00
options.warmup_count = matches
.value_of("warmup")
.and_then(&str_to_u64)
.unwrap_or(0);
2018-01-13 21:01:30 +01:00
if let Some(min_runs) = matches.value_of("min-runs").and_then(&str_to_u64) {
options.min_runs = cmp::max(1, min_runs);
}
2018-01-14 12:39:58 +01:00
options.ignore_failure = matches.is_present("ignore-failure");
2018-01-14 12:03:34 +01:00
let commands = matches.values_of("command").unwrap().collect();
let res = run(&commands, &options);
2018-01-14 10:48:47 +01:00
2018-01-14 12:03:34 +01:00
match res {
Err(e) => error(e.description()),
Ok(_) => {}
2018-01-13 16:50:02 +01:00
}
}