mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-11-03 01:21:25 +00:00
Runs => Measurements
This commit is contained in:
1 parent
8ba632c954
commit
d4c6b53e40
8 files changed
+146
-232
No files matched your search
@@ -1,119 +1,8 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use statistical::{mean, median, standard_deviation};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{benchmark::measurement::Measurements, util::units::Second};
|
||||||
outlier_detection::modified_zscores,
|
|
||||||
util::{
|
|
||||||
min_max::{max, min},
|
|
||||||
units::Second,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Performance metrics and exit codes for each run
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
|
||||||
pub struct Run {
|
|
||||||
/// Wall clock time measurement
|
|
||||||
pub wall_clock_time: Second,
|
|
||||||
|
|
||||||
/// Time spent in user mode
|
|
||||||
pub user_time: Second,
|
|
||||||
|
|
||||||
/// Time spent in kernel mode
|
|
||||||
pub system_time: Second,
|
|
||||||
|
|
||||||
/// Maximum memory usage of the process, in bytes
|
|
||||||
pub memory_usage_byte: u64,
|
|
||||||
|
|
||||||
/// Exit codes of the process
|
|
||||||
pub exit_code: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
|
||||||
pub struct Runs {
|
|
||||||
pub runs: Vec<Run>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Runs {
|
|
||||||
pub fn new(runs: Vec<Run>) -> Self {
|
|
||||||
Self { runs }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.runs.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.runs.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(&mut self, run: Run) {
|
|
||||||
self.runs.push(run);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wall_clock_times(&self) -> Vec<Second> {
|
|
||||||
self.runs.iter().map(|run| run.wall_clock_time).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The average wall clock time
|
|
||||||
pub fn mean(&self) -> Second {
|
|
||||||
mean(&self.wall_clock_times())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The standard deviation of all wall clock times. Not available if only one run has been performed
|
|
||||||
pub fn stddev(&self) -> Option<Second> {
|
|
||||||
let times = self.wall_clock_times();
|
|
||||||
|
|
||||||
let t_mean = mean(×);
|
|
||||||
if times.len() > 1 {
|
|
||||||
Some(standard_deviation(×, Some(t_mean)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The median wall clock time
|
|
||||||
pub fn median(&self) -> Second {
|
|
||||||
median(&self.wall_clock_times())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The minimum wall clock time
|
|
||||||
pub fn min(&self) -> Second {
|
|
||||||
min(&self.wall_clock_times())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The maximum wall clock time
|
|
||||||
pub fn max(&self) -> Second {
|
|
||||||
max(&self.wall_clock_times())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The average user time
|
|
||||||
pub fn user_mean(&self) -> Second {
|
|
||||||
mean(
|
|
||||||
&self
|
|
||||||
.runs
|
|
||||||
.iter()
|
|
||||||
.map(|run| run.user_time)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The average system time
|
|
||||||
pub fn system_mean(&self) -> Second {
|
|
||||||
mean(
|
|
||||||
&self
|
|
||||||
.runs
|
|
||||||
.iter()
|
|
||||||
.map(|run| run.system_time)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn modified_zscores(&self) -> Vec<f64> {
|
|
||||||
modified_zscores(&self.wall_clock_times())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parameter value and whether it was used in the command line template
|
/// Parameter value and whether it was used in the command line template
|
||||||
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
||||||
@@ -137,9 +26,9 @@ pub struct BenchmarkResult {
|
|||||||
/// The full command line of the program that is being benchmarked
|
/// The full command line of the program that is being benchmarked
|
||||||
pub command: String,
|
pub command: String,
|
||||||
|
|
||||||
/// Performance metrics and exit codes for each run
|
/// Performance metric measurements and exit codes for each run
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub runs: Runs,
|
pub measurements: Measurements,
|
||||||
|
|
||||||
/// Parameter values for this benchmark
|
/// Parameter values for this benchmark
|
||||||
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
@@ -149,7 +38,7 @@ pub struct BenchmarkResult {
|
|||||||
impl BenchmarkResult {
|
impl BenchmarkResult {
|
||||||
/// The average wall clock time
|
/// The average wall clock time
|
||||||
pub fn mean_wall_clock_time(&self) -> Second {
|
pub fn mean_wall_clock_time(&self) -> Second {
|
||||||
self.runs.mean()
|
self.measurements.mean()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The full command line of the program that is being benchmarked, possibly including a list of
|
/// The full command line of the program that is being benchmarked, possibly including a list of
|
||||||
|
|||||||
@@ -1,29 +1,33 @@
|
|||||||
use std::process::ExitStatus;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::quantity::statistics::{max, mean, median, min, modified_zscores, standard_deviation};
|
use statistical::{mean, median, standard_deviation};
|
||||||
use crate::quantity::{Information, Time};
|
|
||||||
|
|
||||||
/// Performance measurements and exit status from running a single command
|
use crate::util::units::Second;
|
||||||
#[derive(Debug, Default, Copy, Clone, PartialEq)]
|
use crate::{
|
||||||
|
outlier_detection::modified_zscores,
|
||||||
|
util::min_max::{max, min},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Performance metric measurements and exit code for a single run
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
||||||
pub struct Measurement {
|
pub struct Measurement {
|
||||||
/// Wall clock time
|
/// Elapsed wall clock time (real time)
|
||||||
pub time_wall_clock: Time,
|
pub wall_clock_time: Second,
|
||||||
|
|
||||||
/// Time spent in user mode
|
/// Time spent in user mode
|
||||||
pub time_user: Time,
|
pub user_time: Second,
|
||||||
|
|
||||||
/// Time spent in kernel mode
|
/// Time spent in kernel mode
|
||||||
pub time_system: Time,
|
pub system_time: Second,
|
||||||
|
|
||||||
/// Maximum amount of memory used
|
/// Maximum memory usage of the process, in bytes
|
||||||
pub peak_memory_usage: Information,
|
pub memory_usage_byte: u64,
|
||||||
|
|
||||||
/// The exit status of the process
|
/// Exit codes of the process
|
||||||
pub exit_status: ExitStatus,
|
pub exit_code: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Performance measurements and exit statuses for all runs of a command.
|
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
|
||||||
#[derive(Debug, Default, Clone, PartialEq)]
|
|
||||||
pub struct Measurements {
|
pub struct Measurements {
|
||||||
pub measurements: Vec<Measurement>,
|
pub measurements: Vec<Measurement>,
|
||||||
}
|
}
|
||||||
@@ -45,54 +49,69 @@ impl Measurements {
|
|||||||
self.measurements.push(measurement);
|
self.measurements.push(measurement);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wall_clock_times(&self) -> impl Iterator<Item = Time> + '_ {
|
pub fn wall_clock_times(&self) -> Vec<Second> {
|
||||||
self.measurements.iter().map(|m| m.time_wall_clock)
|
self.measurements
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.wall_clock_time)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The average wall clock time.
|
/// The average wall clock time
|
||||||
pub fn time_wall_clock_mean(&self) -> Time {
|
pub fn mean(&self) -> Second {
|
||||||
mean(self.wall_clock_times())
|
mean(&self.wall_clock_times())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The standard deviation of all wall clock times. Not available if only one run has been performed
|
/// The standard deviation of all wall clock times. Not available if only one run has been performed
|
||||||
pub fn stddev(&self) -> Option<Time> {
|
pub fn stddev(&self) -> Option<Second> {
|
||||||
let times: Vec<_> = self.wall_clock_times().collect(); // TODO: Avoid collecting
|
let times = self.wall_clock_times();
|
||||||
|
|
||||||
if times.len() < 2 {
|
let t_mean = mean(×);
|
||||||
None
|
if times.len() > 1 {
|
||||||
|
Some(standard_deviation(×, Some(t_mean)))
|
||||||
} else {
|
} else {
|
||||||
Some(standard_deviation(times))
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The median wall clock time.
|
/// The median wall clock time
|
||||||
pub fn median(&self) -> Time {
|
pub fn median(&self) -> Second {
|
||||||
median(self.wall_clock_times())
|
median(&self.wall_clock_times())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The minimum wall clock time.
|
/// The minimum wall clock time
|
||||||
pub fn min(&self) -> Time {
|
pub fn min(&self) -> Second {
|
||||||
min(self.wall_clock_times())
|
min(&self.wall_clock_times())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum wall clock time.
|
/// The maximum wall clock time
|
||||||
pub fn max(&self) -> Time {
|
pub fn max(&self) -> Second {
|
||||||
max(self.wall_clock_times())
|
max(&self.wall_clock_times())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The average user time
|
||||||
|
pub fn user_mean(&self) -> Second {
|
||||||
|
mean(
|
||||||
|
&self
|
||||||
|
.measurements
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.user_time)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The average system time
|
||||||
|
pub fn system_mean(&self) -> Second {
|
||||||
|
mean(
|
||||||
|
&self
|
||||||
|
.measurements
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.system_time)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute modified Z-scores for the wall clock times.
|
|
||||||
pub fn modified_zscores(&self) -> Vec<f64> {
|
pub fn modified_zscores(&self) -> Vec<f64> {
|
||||||
modified_zscores(&self.wall_clock_times().collect::<Vec<_>>())
|
modified_zscores(&self.wall_clock_times())
|
||||||
}
|
|
||||||
|
|
||||||
/// The average user time.
|
|
||||||
pub fn time_user_mean(&self) -> Time {
|
|
||||||
mean(self.measurements.iter().map(|m| m.time_user))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The average system time.
|
|
||||||
pub fn time_system_mean(&self) -> Time {
|
|
||||||
mean(self.measurements.iter().map(|m| m.time_system))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn peak_memory_usage_mean(&self) -> Information {
|
pub fn peak_memory_usage_mean(&self) -> Information {
|
||||||
|
|||||||
+19
-17
@@ -8,8 +8,9 @@ use std::cmp;
|
|||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::benchmark::benchmark_result::{Parameter, Run, Runs};
|
use crate::benchmark::benchmark_result::Parameter;
|
||||||
use crate::benchmark::executor::BenchmarkIteration;
|
use crate::benchmark::executor::BenchmarkIteration;
|
||||||
|
use crate::benchmark::measurement::{Measurement, Measurements};
|
||||||
use crate::command::Command;
|
use crate::command::Command;
|
||||||
use crate::options::{
|
use crate::options::{
|
||||||
CmdFailureAction, CommandOutputPolicy, ExecutorKind, Options, OutputStyleOption,
|
CmdFailureAction, CommandOutputPolicy, ExecutorKind, Options, OutputStyleOption,
|
||||||
@@ -170,7 +171,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut runs = Runs::default();
|
let mut measurements = Measurements::default();
|
||||||
let mut all_succeeded = true;
|
let mut all_succeeded = true;
|
||||||
|
|
||||||
let output_policy = &self.options.command_output_policies[self.number];
|
let output_policy = &self.options.command_output_policies[self.number];
|
||||||
@@ -318,7 +319,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
let count_remaining = count - 1;
|
let count_remaining = count - 1;
|
||||||
|
|
||||||
// Save the first result
|
// Save the first result
|
||||||
runs.push(Run {
|
measurements.push(Measurement {
|
||||||
wall_clock_time: res.time_wall_clock,
|
wall_clock_time: res.time_wall_clock,
|
||||||
user_time: res.time_user,
|
user_time: res.time_user,
|
||||||
system_time: res.time_system,
|
system_time: res.time_system,
|
||||||
@@ -339,7 +340,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
let benchmark_iteration = BenchmarkIteration::Benchmark(i + 1);
|
let benchmark_iteration = BenchmarkIteration::Benchmark(i + 1);
|
||||||
|
|
||||||
let msg = {
|
let msg = {
|
||||||
let mean = format_duration(runs.mean(), self.options.time_unit);
|
let mean = format_duration(measurements.mean(), self.options.time_unit);
|
||||||
format!("Current estimate: {}", mean.to_string().green())
|
format!("Current estimate: {}", mean.to_string().green())
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -357,7 +358,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
)?;
|
)?;
|
||||||
let success = res.exit_status.success();
|
let success = res.exit_status.success();
|
||||||
|
|
||||||
runs.push(Run {
|
measurements.push(Measurement {
|
||||||
wall_clock_time: res.time_wall_clock,
|
wall_clock_time: res.time_wall_clock,
|
||||||
user_time: res.time_user,
|
user_time: res.time_user,
|
||||||
system_time: res.time_system,
|
system_time: res.time_system,
|
||||||
@@ -379,16 +380,17 @@ impl<'a> Benchmark<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Formatting and console output
|
// Formatting and console output
|
||||||
let (mean_str, time_unit) = format_duration_unit(runs.mean(), self.options.time_unit);
|
let (mean_str, time_unit) =
|
||||||
let min_str = format_duration(runs.min(), Some(time_unit));
|
format_duration_unit(measurements.mean(), self.options.time_unit);
|
||||||
let max_str = format_duration(runs.max(), Some(time_unit));
|
let min_str = format_duration(measurements.min(), Some(time_unit));
|
||||||
let num_str = format!("{num_runs} runs", num_runs = runs.len());
|
let max_str = format_duration(measurements.max(), Some(time_unit));
|
||||||
|
let num_str = format!("{num_runs} runs", num_runs = measurements.len());
|
||||||
|
|
||||||
let user_str = format_duration(runs.user_mean(), Some(time_unit));
|
let user_str = format_duration(measurements.user_mean(), Some(time_unit));
|
||||||
let system_str = format_duration(runs.system_mean(), Some(time_unit));
|
let system_str = format_duration(measurements.system_mean(), Some(time_unit));
|
||||||
|
|
||||||
if self.options.output_style != OutputStyleOption::Disabled {
|
if self.options.output_style != OutputStyleOption::Disabled {
|
||||||
if runs.len() == 1 {
|
if measurements.len() == 1 {
|
||||||
println!(
|
println!(
|
||||||
" Time ({} ≡): {:>8} {:>8} [User: {}, System: {}]",
|
" Time ({} ≡): {:>8} {:>8} [User: {}, System: {}]",
|
||||||
"abs".green().bold(),
|
"abs".green().bold(),
|
||||||
@@ -398,7 +400,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
system_str.blue()
|
system_str.blue()
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let stddev_str = format_duration(runs.stddev().unwrap(), Some(time_unit));
|
let stddev_str = format_duration(measurements.stddev().unwrap(), Some(time_unit));
|
||||||
|
|
||||||
console_writeln!(
|
console_writeln!(
|
||||||
stdout,
|
stdout,
|
||||||
@@ -428,7 +430,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
|
|
||||||
// Check execution time
|
// Check execution time
|
||||||
if matches!(self.options.executor_kind, ExecutorKind::Shell(_))
|
if matches!(self.options.executor_kind, ExecutorKind::Shell(_))
|
||||||
&& runs
|
&& measurements
|
||||||
.wall_clock_times()
|
.wall_clock_times()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|&t| t < MIN_EXECUTION_TIME)
|
.any(|&t| t < MIN_EXECUTION_TIME)
|
||||||
@@ -442,7 +444,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run outlier detection
|
// Run outlier detection
|
||||||
let scores = runs.modified_zscores();
|
let scores = measurements.modified_zscores();
|
||||||
|
|
||||||
let outlier_warning_options = OutlierWarningOptions {
|
let outlier_warning_options = OutlierWarningOptions {
|
||||||
warmup_in_use: self.options.warmup_count > 0,
|
warmup_in_use: self.options.warmup_count > 0,
|
||||||
@@ -457,7 +459,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
|
|
||||||
if scores[0] > OUTLIER_THRESHOLD {
|
if scores[0] > OUTLIER_THRESHOLD {
|
||||||
warnings.push(Warnings::SlowInitialRun(
|
warnings.push(Warnings::SlowInitialRun(
|
||||||
runs.wall_clock_times()[0],
|
measurements.wall_clock_times()[0],
|
||||||
outlier_warning_options,
|
outlier_warning_options,
|
||||||
));
|
));
|
||||||
} else if scores.iter().any(|&s| s.abs() > OUTLIER_THRESHOLD) {
|
} else if scores.iter().any(|&s| s.abs() > OUTLIER_THRESHOLD) {
|
||||||
@@ -481,7 +483,7 @@ impl<'a> Benchmark<'a> {
|
|||||||
|
|
||||||
Ok(BenchmarkResult {
|
Ok(BenchmarkResult {
|
||||||
command: self.command.get_name(),
|
command: self.command.get_name(),
|
||||||
runs,
|
measurements,
|
||||||
parameters: self
|
parameters: self
|
||||||
.command
|
.command
|
||||||
.get_parameters()
|
.get_parameters()
|
||||||
|
|||||||
@@ -152,12 +152,12 @@ pub fn compute<'a>(
|
|||||||
fn create_result(name: &str, mean: f64) -> BenchmarkResult {
|
fn create_result(name: &str, mean: f64) -> BenchmarkResult {
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use crate::benchmark::benchmark_result::{Run, Runs};
|
use crate::benchmark::measurement::{Measurement, Measurements};
|
||||||
|
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: name.into(),
|
command: name.into(),
|
||||||
runs: Runs {
|
measurements: Measurements {
|
||||||
runs: vec![Run {
|
measurements: vec![Measurement {
|
||||||
wall_clock_time: mean,
|
wall_clock_time: mean,
|
||||||
user_time: mean,
|
user_time: mean,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ fn generate_results(args: &[&'static str]) -> Result<Vec<BenchmarkResult>> {
|
|||||||
fn scheduler_basic() -> Result<()> {
|
fn scheduler_basic() -> Result<()> {
|
||||||
insta::assert_yaml_snapshot!(generate_results(&["--runs=2", "sleep 0.123", "sleep 0.456"])?, @r#"
|
insta::assert_yaml_snapshot!(generate_results(&["--runs=2", "sleep 0.123", "sleep 0.456"])?, @r#"
|
||||||
- command: sleep 0.123
|
- command: sleep 0.123
|
||||||
runs:
|
measurements:
|
||||||
- wall_clock_time: 0.123
|
- wall_clock_time: 0.123
|
||||||
user_time: 0
|
user_time: 0
|
||||||
system_time: 0
|
system_time: 0
|
||||||
@@ -217,7 +217,7 @@ fn scheduler_basic() -> Result<()> {
|
|||||||
memory_usage_byte: 0
|
memory_usage_byte: 0
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
- command: sleep 0.456
|
- command: sleep 0.456
|
||||||
runs:
|
measurements:
|
||||||
- wall_clock_time: 0.456
|
- wall_clock_time: 0.456
|
||||||
user_time: 0
|
user_time: 0
|
||||||
system_time: 0
|
system_time: 0
|
||||||
|
|||||||
+18
-15
@@ -45,12 +45,12 @@ impl Exporter for CsvExporter {
|
|||||||
let mut fields = vec![Cow::Borrowed(res.command.as_bytes())];
|
let mut fields = vec![Cow::Borrowed(res.command.as_bytes())];
|
||||||
for f in &[
|
for f in &[
|
||||||
res.mean_wall_clock_time(),
|
res.mean_wall_clock_time(),
|
||||||
res.runs.stddev().unwrap_or(0.0),
|
res.measurements.stddev().unwrap_or(0.0),
|
||||||
res.runs.median(),
|
res.measurements.median(),
|
||||||
res.runs.user_mean(),
|
res.measurements.user_mean(),
|
||||||
res.runs.system_mean(),
|
res.measurements.system_mean(),
|
||||||
res.runs.min(),
|
res.measurements.min(),
|
||||||
res.runs.max(),
|
res.measurements.max(),
|
||||||
] {
|
] {
|
||||||
fields.push(Cow::Owned(
|
fields.push(Cow::Owned(
|
||||||
f.format_with_precision(CSV_UNIT, CSV_PRECISION)
|
f.format_with_precision(CSV_UNIT, CSV_PRECISION)
|
||||||
@@ -68,7 +68,10 @@ impl Exporter for CsvExporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use crate::benchmark::benchmark_result::{Parameter, Run, Runs};
|
use crate::benchmark::benchmark_result::Parameter;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::benchmark::measurement::{Measurement, Measurements};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_csv() {
|
fn test_csv() {
|
||||||
@@ -84,22 +87,22 @@ fn test_csv() {
|
|||||||
let results = vec![
|
let results = vec![
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("command_a"),
|
command: String::from("command_a"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 7.0,
|
wall_clock_time: 7.0,
|
||||||
user_time: 7.0,
|
user_time: 7.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 8.0,
|
wall_clock_time: 8.0,
|
||||||
user_time: 8.0,
|
user_time: 8.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 12.0,
|
wall_clock_time: 12.0,
|
||||||
user_time: 12.0,
|
user_time: 12.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
@@ -128,22 +131,22 @@ fn test_csv() {
|
|||||||
},
|
},
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("command_b"),
|
command: String::from("command_b"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 17.0,
|
wall_clock_time: 17.0,
|
||||||
user_time: 17.0,
|
user_time: 17.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 18.0,
|
wall_clock_time: 18.0,
|
||||||
user_time: 18.0,
|
user_time: 18.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 19.0,
|
wall_clock_time: 19.0,
|
||||||
user_time: 19.0,
|
user_time: 19.0,
|
||||||
system_time: 0.0,
|
system_time: 0.0,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pub trait MarkupExporter {
|
|||||||
// prepare data row strings
|
// prepare data row strings
|
||||||
let cmd_str = result.command_with_unused_parameters().replace('|', "\\|");
|
let cmd_str = result.command_with_unused_parameters().replace('|', "\\|");
|
||||||
let mean_str = format_duration_value(result.mean_wall_clock_time(), Some(unit)).0;
|
let mean_str = format_duration_value(result.mean_wall_clock_time(), Some(unit)).0;
|
||||||
let stddev_str = if let Some(stddev) = result.runs.stddev() {
|
let stddev_str = if let Some(stddev) = result.measurements.stddev() {
|
||||||
format!(" ± {}", format_duration_value(stddev, Some(unit)).0)
|
format!(" ± {}", format_duration_value(stddev, Some(unit)).0)
|
||||||
} else {
|
} else {
|
||||||
"".into()
|
"".into()
|
||||||
|
|||||||
+34
-33
@@ -1,5 +1,6 @@
|
|||||||
use super::Exporter;
|
use super::Exporter;
|
||||||
use crate::benchmark::benchmark_result::{BenchmarkResult, Run, Runs};
|
use crate::benchmark::benchmark_result::BenchmarkResult;
|
||||||
|
use crate::benchmark::measurement::{Measurement, Measurements};
|
||||||
use crate::export::asciidoc::AsciidocExporter;
|
use crate::export::asciidoc::AsciidocExporter;
|
||||||
use crate::export::orgmode::OrgmodeExporter;
|
use crate::export::orgmode::OrgmodeExporter;
|
||||||
use crate::quantity::{byte, second, Information, Time, TimeUnit, Zero};
|
use crate::quantity::{byte, second, Information, Time, TimeUnit, Zero};
|
||||||
@@ -27,22 +28,22 @@ fn test_markup_export_auto_ms() {
|
|||||||
let results = [
|
let results = [
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 0.1"),
|
command: String::from("sleep 0.1"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.09,
|
wall_clock_time: 0.09,
|
||||||
user_time: 0.09,
|
user_time: 0.09,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.10,
|
wall_clock_time: 0.10,
|
||||||
user_time: 0.10,
|
user_time: 0.10,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.14,
|
wall_clock_time: 0.14,
|
||||||
user_time: 0.14,
|
user_time: 0.14,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -54,22 +55,22 @@ fn test_markup_export_auto_ms() {
|
|||||||
},
|
},
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 2"),
|
command: String::from("sleep 2"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.0,
|
wall_clock_time: 2.0,
|
||||||
user_time: 2.0,
|
user_time: 2.0,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 3.0,
|
wall_clock_time: 3.0,
|
||||||
user_time: 3.0,
|
user_time: 3.0,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 4.0,
|
wall_clock_time: 4.0,
|
||||||
user_time: 4.0,
|
user_time: 4.0,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -126,22 +127,22 @@ fn test_markup_export_auto_s() {
|
|||||||
let results = [
|
let results = [
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 2"),
|
command: String::from("sleep 2"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.1,
|
wall_clock_time: 2.1,
|
||||||
user_time: 2.1,
|
user_time: 2.1,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.2,
|
wall_clock_time: 2.2,
|
||||||
user_time: 2.2,
|
user_time: 2.2,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.3,
|
wall_clock_time: 2.3,
|
||||||
user_time: 2.3,
|
user_time: 2.3,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -153,22 +154,22 @@ fn test_markup_export_auto_s() {
|
|||||||
},
|
},
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 0.1"),
|
command: String::from("sleep 0.1"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.1,
|
wall_clock_time: 0.1,
|
||||||
user_time: 0.1,
|
user_time: 0.1,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.2,
|
wall_clock_time: 0.2,
|
||||||
user_time: 0.2,
|
user_time: 0.2,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.3,
|
wall_clock_time: 0.3,
|
||||||
user_time: 0.3,
|
user_time: 0.3,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -225,22 +226,22 @@ fn test_markup_export_manual_ms() {
|
|||||||
let timing_results = [
|
let timing_results = [
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 2"),
|
command: String::from("sleep 2"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.1,
|
wall_clock_time: 2.1,
|
||||||
user_time: 2.1,
|
user_time: 2.1,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.2,
|
wall_clock_time: 2.2,
|
||||||
user_time: 2.2,
|
user_time: 2.2,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.3,
|
wall_clock_time: 2.3,
|
||||||
user_time: 2.3,
|
user_time: 2.3,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -252,22 +253,22 @@ fn test_markup_export_manual_ms() {
|
|||||||
},
|
},
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 0.1"),
|
command: String::from("sleep 0.1"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.1,
|
wall_clock_time: 0.1,
|
||||||
user_time: 0.1,
|
user_time: 0.1,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.2,
|
wall_clock_time: 0.2,
|
||||||
user_time: 0.2,
|
user_time: 0.2,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.3,
|
wall_clock_time: 0.3,
|
||||||
user_time: 0.3,
|
user_time: 0.3,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -323,22 +324,22 @@ fn test_markup_export_manual_s() {
|
|||||||
let results = [
|
let results = [
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 2"),
|
command: String::from("sleep 2"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.01,
|
wall_clock_time: 2.01,
|
||||||
user_time: 2.01,
|
user_time: 2.01,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.02,
|
wall_clock_time: 2.02,
|
||||||
user_time: 2.02,
|
user_time: 2.02,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 2.03,
|
wall_clock_time: 2.03,
|
||||||
user_time: 2.03,
|
user_time: 2.03,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
@@ -350,22 +351,22 @@ fn test_markup_export_manual_s() {
|
|||||||
},
|
},
|
||||||
BenchmarkResult {
|
BenchmarkResult {
|
||||||
command: String::from("sleep 0.1"),
|
command: String::from("sleep 0.1"),
|
||||||
runs: Runs::new(vec![
|
measurements: Measurements::new(vec![
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.11,
|
wall_clock_time: 0.11,
|
||||||
user_time: 0.11,
|
user_time: 0.11,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.12,
|
wall_clock_time: 0.12,
|
||||||
user_time: 0.12,
|
user_time: 0.12,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
memory_usage_byte: 1024,
|
memory_usage_byte: 1024,
|
||||||
exit_code: Some(0),
|
exit_code: Some(0),
|
||||||
},
|
},
|
||||||
Run {
|
Measurement {
|
||||||
wall_clock_time: 0.13,
|
wall_clock_time: 0.13,
|
||||||
user_time: 0.13,
|
user_time: 0.13,
|
||||||
system_time: 0.,
|
system_time: 0.,
|
||||||
|
|||||||
Reference in new issue
Block a user