mirror of
https://github.com/sharkdp/hyperfine.git
synced 2024-12-02 08:04:56 +03:00
parent
fe041df718
commit
d78c33b864
@ -54,6 +54,22 @@ fn build_app() -> App<'static, 'static> {
|
|||||||
.value_name("NUM")
|
.value_name("NUM")
|
||||||
.help("Perform at least NUM runs for each command (default: 10)."),
|
.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")
|
||||||
|
.help("Perform at most NUM runs for each command."),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("runs")
|
||||||
|
.long("runs")
|
||||||
|
.short("r")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("NUM")
|
||||||
|
.help("Perform exactly NUM runs for each command."),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("prepare")
|
Arg::with_name("prepare")
|
||||||
.long("prepare")
|
.long("prepare")
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::cmp;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ pub fn run_benchmark(
|
|||||||
|
|
||||||
// Set up progress bar (and spinner for initial measurement)
|
// Set up progress bar (and spinner for initial measurement)
|
||||||
let progress_bar = get_progress_bar(
|
let progress_bar = get_progress_bar(
|
||||||
options.min_runs,
|
options.runs.min,
|
||||||
"Initial time measurement",
|
"Initial time measurement",
|
||||||
&options.output_style,
|
&options.output_style,
|
||||||
);
|
);
|
||||||
@ -215,11 +216,10 @@ pub fn run_benchmark(
|
|||||||
/ (res.time_real + prepare_res.time_real + shell_spawning_time.time_real))
|
/ (res.time_real + prepare_res.time_real + shell_spawning_time.time_real))
|
||||||
as u64;
|
as u64;
|
||||||
|
|
||||||
let count = if runs_in_min_time >= options.min_runs {
|
let count = cmp::min(
|
||||||
runs_in_min_time
|
cmp::max(runs_in_min_time, options.runs.min),
|
||||||
} else {
|
options.runs.max
|
||||||
options.min_runs
|
);
|
||||||
};
|
|
||||||
|
|
||||||
let count_remaining = count - 1;
|
let count_remaining = count - 1;
|
||||||
|
|
||||||
|
@ -9,16 +9,6 @@ pub enum ParameterScanError {
|
|||||||
TooLarge,
|
TooLarge,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParameterScanError {
|
|
||||||
fn __description(&self) -> &str {
|
|
||||||
match *self {
|
|
||||||
ParameterScanError::ParseIntError(ref e) => e.description(),
|
|
||||||
ParameterScanError::EmptyRange => "Empty parameter range",
|
|
||||||
ParameterScanError::TooLarge => "Parameter range is too large",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<num::ParseIntError> for ParameterScanError {
|
impl From<num::ParseIntError> for ParameterScanError {
|
||||||
fn from(e: num::ParseIntError) -> ParameterScanError {
|
fn from(e: num::ParseIntError) -> ParameterScanError {
|
||||||
ParameterScanError::ParseIntError(e)
|
ParameterScanError::ParseIntError(e)
|
||||||
@ -27,12 +17,37 @@ impl From<num::ParseIntError> for ParameterScanError {
|
|||||||
|
|
||||||
impl fmt::Display for ParameterScanError {
|
impl fmt::Display for ParameterScanError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.__description())
|
write!(f, "{}", self.description())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ParameterScanError {
|
impl Error for ParameterScanError {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
self.__description()
|
match *self {
|
||||||
|
ParameterScanError::ParseIntError(ref e) => e.description(),
|
||||||
|
ParameterScanError::EmptyRange => "Empty parameter range",
|
||||||
|
ParameterScanError::TooLarge => "Parameter range is too large",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum OptionsError {
|
||||||
|
RunsBelowTwo,
|
||||||
|
EmptyRunsRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for OptionsError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.description())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for OptionsError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
match *self {
|
||||||
|
OptionsError::EmptyRunsRange => "Empty runs range",
|
||||||
|
OptionsError::RunsBelowTwo => "Number of runs below two",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,13 +73,31 @@ pub enum OutputStyleOption {
|
|||||||
NoColor,
|
NoColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Number of runs for a benchmark
|
||||||
|
pub struct Runs {
|
||||||
|
/// Minimum number of benchmark runs
|
||||||
|
pub min: u64,
|
||||||
|
|
||||||
|
/// Maximum number of benchmark runs
|
||||||
|
pub max: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Runs {
|
||||||
|
fn default() -> Runs {
|
||||||
|
Runs {
|
||||||
|
min: 10,
|
||||||
|
max: ::std::u64::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A set of options for hyperfine
|
/// A set of options for hyperfine
|
||||||
pub struct HyperfineOptions {
|
pub struct HyperfineOptions {
|
||||||
/// Number of warmup runs
|
/// Number of warmup runs
|
||||||
pub warmup_count: u64,
|
pub warmup_count: u64,
|
||||||
|
|
||||||
/// Minimum number of benchmark runs
|
/// Number of benchmark runs
|
||||||
pub min_runs: u64,
|
pub runs: Runs,
|
||||||
|
|
||||||
/// Minimum benchmarking time
|
/// Minimum benchmarking time
|
||||||
pub min_time_sec: Second,
|
pub min_time_sec: Second,
|
||||||
@ -101,7 +119,7 @@ impl Default for HyperfineOptions {
|
|||||||
fn default() -> HyperfineOptions {
|
fn default() -> HyperfineOptions {
|
||||||
HyperfineOptions {
|
HyperfineOptions {
|
||||||
warmup_count: 0,
|
warmup_count: 0,
|
||||||
min_runs: 10,
|
runs: Runs::default(),
|
||||||
min_time_sec: 3.0,
|
min_time_sec: 3.0,
|
||||||
failure_action: CmdFailureAction::RaiseError,
|
failure_action: CmdFailureAction::RaiseError,
|
||||||
preparation_command: None,
|
preparation_command: None,
|
||||||
|
47
src/main.rs
47
src/main.rs
@ -42,7 +42,7 @@ mod hyperfine;
|
|||||||
|
|
||||||
use hyperfine::app::get_arg_matches;
|
use hyperfine::app::get_arg_matches;
|
||||||
use hyperfine::benchmark::{mean_shell_spawning_time, run_benchmark};
|
use hyperfine::benchmark::{mean_shell_spawning_time, run_benchmark};
|
||||||
use hyperfine::error::ParameterScanError;
|
use hyperfine::error::{ParameterScanError, OptionsError};
|
||||||
use hyperfine::export::{ExportManager, ExportType};
|
use hyperfine::export::{ExportManager, ExportType};
|
||||||
use hyperfine::internal::write_benchmark_comparison;
|
use hyperfine::internal::write_benchmark_comparison;
|
||||||
use hyperfine::types::{
|
use hyperfine::types::{
|
||||||
@ -95,7 +95,10 @@ fn main() {
|
|||||||
let export_manager = build_export_manager(&matches);
|
let export_manager = build_export_manager(&matches);
|
||||||
let commands = build_commands(&matches);
|
let commands = build_commands(&matches);
|
||||||
|
|
||||||
let res = run(&commands, &options);
|
let res = match options {
|
||||||
|
Ok(opts) => run(&commands, &opts),
|
||||||
|
Err(e) => error(e.description()),
|
||||||
|
};
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(timing_results) => {
|
Ok(timing_results) => {
|
||||||
@ -113,7 +116,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Build the HyperfineOptions that correspond to the given ArgMatches
|
/// Build the HyperfineOptions that correspond to the given ArgMatches
|
||||||
fn build_hyperfine_options(matches: &ArgMatches) -> HyperfineOptions {
|
fn build_hyperfine_options(matches: &ArgMatches) -> Result<HyperfineOptions, OptionsError> {
|
||||||
let mut options = HyperfineOptions::default();
|
let mut options = HyperfineOptions::default();
|
||||||
let str_to_u64 = |n| u64::from_str_radix(n, 10).ok();
|
let str_to_u64 = |n| u64::from_str_radix(n, 10).ok();
|
||||||
|
|
||||||
@ -122,11 +125,41 @@ fn build_hyperfine_options(matches: &ArgMatches) -> HyperfineOptions {
|
|||||||
.and_then(&str_to_u64)
|
.and_then(&str_to_u64)
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
if let Some(min_runs) = matches.value_of("min-runs").and_then(&str_to_u64) {
|
let mut min_runs = matches.value_of("min-runs").and_then(&str_to_u64);
|
||||||
// we need at least two runs to compute a variance
|
let mut max_runs = matches.value_of("max-runs").and_then(&str_to_u64);
|
||||||
options.min_runs = cmp::max(2, min_runs);
|
|
||||||
|
if let Some(runs) = matches.value_of("runs").and_then(&str_to_u64) {
|
||||||
|
min_runs = Some(runs);
|
||||||
|
max_runs = Some(runs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match (min_runs, max_runs) {
|
||||||
|
(Some(min), _) if min < 2 => {
|
||||||
|
// We need at least two runs to compute a variance.
|
||||||
|
return Err(OptionsError::RunsBelowTwo);
|
||||||
|
}
|
||||||
|
(Some(min), None) => {
|
||||||
|
options.runs.min = min;
|
||||||
|
}
|
||||||
|
(_, Some(max)) if max < 2 => {
|
||||||
|
// We need at least two runs to compute a variance.
|
||||||
|
return Err(OptionsError::RunsBelowTwo);
|
||||||
|
}
|
||||||
|
(None, Some(max)) => {
|
||||||
|
// Since the minimum was not explicit we lower it if max is below the default min.
|
||||||
|
options.runs.min = cmp::min(options.runs.min, max);
|
||||||
|
options.runs.max = max;
|
||||||
|
}
|
||||||
|
(Some(min), Some(max)) if min > max => {
|
||||||
|
return Err(OptionsError::EmptyRunsRange);
|
||||||
|
}
|
||||||
|
(Some(min), Some(max)) => {
|
||||||
|
options.runs.min = min;
|
||||||
|
options.runs.max = max;
|
||||||
|
}
|
||||||
|
(None, None) => {}
|
||||||
|
};
|
||||||
|
|
||||||
options.preparation_command = matches.value_of("prepare").map(String::from);
|
options.preparation_command = matches.value_of("prepare").map(String::from);
|
||||||
|
|
||||||
options.show_output = matches.is_present("show-output");
|
options.show_output = matches.is_present("show-output");
|
||||||
@ -155,7 +188,7 @@ fn build_hyperfine_options(matches: &ArgMatches) -> HyperfineOptions {
|
|||||||
options.failure_action = CmdFailureAction::Ignore;
|
options.failure_action = CmdFailureAction::Ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
options
|
Ok(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the ExportManager that will export the results specified
|
/// Build the ExportManager that will export the results specified
|
||||||
|
Loading…
Reference in New Issue
Block a user