Skip to content
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## v1.20.0

## Features

- Add reporting for both I/O operations for windows in the benchmark results.
and I/O operations and context switching counts for linux in benchmark results(@mahmoudkhera)

# v1.19.0

## Features
Expand Down
6 changes: 6 additions & 0 deletions src/benchmark/.scheduler.rs.pending-snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"run_id":"1758214527-208262000","line":190,"new":{"module_name":"hyperfine__benchmark__scheduler","snapshot_name":"scheduler_basic","metadata":{"source":"src/benchmark/scheduler.rs","assertion_line":190,"expression":"generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?","snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"},"old":{"module_name":"hyperfine__benchmark__scheduler","metadata":{"snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"}}
{"run_id":"1758214573-45664400","line":190,"new":{"module_name":"hyperfine__benchmark__scheduler","snapshot_name":"scheduler_basic","metadata":{"source":"src/benchmark/scheduler.rs","assertion_line":190,"expression":"generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?","snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"},"old":{"module_name":"hyperfine__benchmark__scheduler","metadata":{"snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"}}
{"run_id":"1758214769-787501100","line":190,"new":{"module_name":"hyperfine__benchmark__scheduler","snapshot_name":"scheduler_basic","metadata":{"source":"src/benchmark/scheduler.rs","assertion_line":190,"expression":"generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?","snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"},"old":{"module_name":"hyperfine__benchmark__scheduler","metadata":{"snapshot_kind":"text"},"snapshot":"insta::assert_yaml_snapshot!(generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?, @r#\"\n - command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0 \n exit_codes:\n - 0\n - 0\n - command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0 \n exit_codes:\n - 0\n - 0"}}
{"run_id":"1758214798-792806100","line":190,"new":{"module_name":"hyperfine__benchmark__scheduler","snapshot_name":"scheduler_basic","metadata":{"source":"src/benchmark/scheduler.rs","assertion_line":190,"expression":"generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?","snapshot_kind":"text"},"snapshot":"- command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0\n- command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0\n exit_codes:\n - 0\n - 0"},"old":{"module_name":"hyperfine__benchmark__scheduler","metadata":{"snapshot_kind":"text"},"snapshot":"insta::assert_yaml_snapshot!(generate_results(&[\"--runs=2\", \"sleep 0.123\", \"sleep 0.456\"])?, @r#\"\n - command: sleep 0.123\n mean: 0.123\n stddev: 0\n median: 0.123\n user: 0\n system: 0\n min: 0.123\n max: 0.123\n times:\n - 0.123\n - 0.123\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0 \n exit_codes:\n - 0\n - 0\n - command: sleep 0.456\n mean: 0.456\n stddev: 0\n median: 0.456\n user: 0\n system: 0\n min: 0.456\n max: 0.456\n times:\n - 0.456\n - 0.456\n memory_usage_byte:\n - 0\n - 0\n voluntary_cs:\n - 0\n - 0\n involuntary_cs:\n - 0\n - 0\n io_read_ops:\n - 0\n - 0\n io_write_ops:\n - 0\n - 0 \n exit_codes:\n - 0\n - 0"}}
{"run_id":"1758214893-602072100","line":190,"new":null,"old":null}
{"run_id":"1758214997-865403300","line":190,"new":null,"old":null}
14 changes: 14 additions & 0 deletions src/benchmark/benchmark_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ pub struct BenchmarkResult {
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_usage_byte: Option<Vec<u64>>,

/// All the voluntary context switching
#[serde(skip_serializing_if = "Option::is_none")]
pub voluntary_cs: Option<Vec<u64>>,
/// All the involuntary context switching
#[serde(skip_serializing_if = "Option::is_none")]
pub involuntary_cs: Option<Vec<u64>>,

/// All io read operations
#[serde(skip_serializing_if = "Option::is_none")]
pub io_read_ops: Option<Vec<u64>>,
/// All io write operations
#[serde(skip_serializing_if = "Option::is_none")]
pub io_write_ops: Option<Vec<u64>>,

/// Exit codes of all command invocations
pub exit_codes: Vec<Option<i32>>,

Expand Down
16 changes: 16 additions & 0 deletions src/benchmark/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ impl Executor for RawExecutor<'_> {
time_user: result.time_user,
time_system: result.time_system,
memory_usage_byte: result.memory_usage_byte,
voluntary_cs: result.voluntary_cs,
involuntary_cs: result.involuntary_cs,
io_read_ops: result.io_read_ops,
io_write_ops: result.io_write_ops,
},
result.status,
))
Expand Down Expand Up @@ -206,6 +210,10 @@ impl Executor for ShellExecutor<'_> {
time_user: result.time_user,
time_system: result.time_system,
memory_usage_byte: result.memory_usage_byte,
voluntary_cs: result.voluntary_cs,
involuntary_cs: result.involuntary_cs,
io_read_ops: result.io_read_ops,
io_write_ops: result.io_write_ops,
},
result.status,
))
Expand Down Expand Up @@ -270,6 +278,10 @@ impl Executor for ShellExecutor<'_> {
time_real: mean(&times_real),
time_user: mean(&times_user),
time_system: mean(&times_system),
voluntary_cs: 0,
involuntary_cs: 0,
io_read_ops: 0,
io_write_ops: 0,
memory_usage_byte: 0,
});

Expand Down Expand Up @@ -327,6 +339,10 @@ impl Executor for MockExecutor {
time_user: 0.0,
time_system: 0.0,
memory_usage_byte: 0,
voluntary_cs: 0,
involuntary_cs: 0,
io_read_ops: 0,
io_write_ops: 0,
},
status,
))
Expand Down
46 changes: 46 additions & 0 deletions src/benchmark/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ impl<'a> Benchmark<'a> {
let mut times_system: Vec<Second> = vec![];
let mut memory_usage_byte: Vec<u64> = vec![];
let mut exit_codes: Vec<Option<i32>> = vec![];
let mut voluntary_cs: Vec<u64> = vec![];
let mut involuntary_cs: Vec<u64> = vec![];
let mut io_read_ops: Vec<u64> = vec![];
let mut io_write_ops: Vec<u64> = vec![];

let mut all_succeeded = true;

let output_policy = &self.options.command_output_policies[self.number];
Expand Down Expand Up @@ -281,6 +286,10 @@ impl<'a> Benchmark<'a> {
times_user.push(res.time_user);
times_system.push(res.time_system);
memory_usage_byte.push(res.memory_usage_byte);
voluntary_cs.push(res.voluntary_cs);
involuntary_cs.push(res.involuntary_cs);
io_read_ops.push(res.io_read_ops);
io_write_ops.push(res.io_write_ops);
exit_codes.push(extract_exit_code(status));

all_succeeded = all_succeeded && success;
Expand Down Expand Up @@ -318,6 +327,10 @@ impl<'a> Benchmark<'a> {
times_user.push(res.time_user);
times_system.push(res.time_system);
memory_usage_byte.push(res.memory_usage_byte);
voluntary_cs.push(res.voluntary_cs);
involuntary_cs.push(res.involuntary_cs);
io_read_ops.push(res.io_read_ops);
io_write_ops.push(res.io_write_ops);
exit_codes.push(extract_exit_code(status));

all_succeeded = all_succeeded && success;
Expand Down Expand Up @@ -347,6 +360,15 @@ impl<'a> Benchmark<'a> {

let user_mean = mean(&times_user);
let system_mean = mean(&times_system);
#[cfg(not(windows))]
let (vcs, invcs) = {
let total_voluntary_cs = voluntary_cs.iter().fold(0, |acc, x| acc + x);
let total_involuntary_cs = involuntary_cs.iter().fold(0, |acc, x| acc + x);

(total_voluntary_cs, total_involuntary_cs)
};
let total_io_read_ops = io_read_ops.iter().fold(0, |acc, x| acc + x);
let total_io_write_ops = io_write_ops.iter().fold(0, |acc, x| acc + x);

// Formatting and console output
let (mean_str, time_unit) = format_duration_unit(t_mean, self.options.time_unit);
Expand Down Expand Up @@ -388,6 +410,26 @@ impl<'a> Benchmark<'a> {
max_str.purple(),
num_str.dimmed()
);
println!("\n extra stats");
// Print IO operations
println!(
" {:<20} {:<20} {}/{} \n",
"IO Operations".cyan(),
"Read/Write".purple(),
total_io_read_ops.to_string().green(),
total_io_write_ops.to_string().green(),
);

// Print context switches if not windows
#[cfg(not(windows))]

println!(
" {:<20} {:<20} {}/{:<8} ",
"Context Switches".cyan(),
"vcs/invcs".purple(),
vcs.to_string().green(),
invcs.to_string().green(),
);
}
}

Expand Down Expand Up @@ -454,6 +496,10 @@ impl<'a> Benchmark<'a> {
min: t_min,
max: t_max,
times: Some(times_real),
voluntary_cs: Some(voluntary_cs),
involuntary_cs: Some(involuntary_cs),
io_read_ops: Some(io_read_ops),
io_write_ops: Some(io_write_ops),
memory_usage_byte: Some(memory_usage_byte),
exit_codes,
parameters: self
Expand Down
1 change: 1 addition & 0 deletions src/benchmark/relative_speed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ fn create_result(name: &str, mean: Scalar) -> BenchmarkResult {
memory_usage_byte: None,
exit_codes: Vec::new(),
parameters: BTreeMap::new(),
..Default::default()
}
}

Expand Down
24 changes: 24 additions & 0 deletions src/benchmark/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,18 @@ fn scheduler_basic() -> Result<()> {
memory_usage_byte:
- 0
- 0
voluntary_cs:
- 0
- 0
involuntary_cs:
- 0
- 0
io_read_ops:
- 0
- 0
io_write_ops:
- 0
- 0
exit_codes:
- 0
- 0
Expand All @@ -219,6 +231,18 @@ fn scheduler_basic() -> Result<()> {
memory_usage_byte:
- 0
- 0
voluntary_cs:
- 0
- 0
involuntary_cs:
- 0
- 0
io_read_ops:
- 0
- 0
io_write_ops:
- 0
- 0
exit_codes:
- 0
- 0
Expand Down
10 changes: 10 additions & 0 deletions src/benchmark/timing_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ pub struct TimingResult {

/// Maximum amount of memory used, in bytes
pub memory_usage_byte: u64,
/// number of voluntary context swithcing
pub voluntary_cs: u64,
/// number of involuntary context swithcing
pub involuntary_cs: u64,

/// number of io read operations
pub io_read_ops: u64,

/// number of io write operations
pub io_write_ops: u64,
}
8 changes: 8 additions & 0 deletions src/export/csv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ fn test_csv() {
max: 6.0,
times: Some(vec![7.0, 8.0, 9.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: {
let mut params = BTreeMap::new();
Expand All @@ -98,6 +102,10 @@ fn test_csv() {
max: 16.5,
times: Some(vec![17.0, 18.0, 19.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: {
let mut params = BTreeMap::new();
Expand Down
33 changes: 33 additions & 0 deletions src/export/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ fn test_markup_export_auto_ms() {
max: 0.1080,
times: Some(vec![0.1, 0.1, 0.1]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,

exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand All @@ -51,6 +56,10 @@ fn test_markup_export_auto_ms() {
max: 2.0080,
times: Some(vec![2.0, 2.0, 2.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand Down Expand Up @@ -111,6 +120,10 @@ fn test_markup_export_auto_s() {
max: 2.0080,
times: Some(vec![2.0, 2.0, 2.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand All @@ -126,6 +139,10 @@ fn test_markup_export_auto_s() {
max: 0.1080,
times: Some(vec![0.1, 0.1, 0.1]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand Down Expand Up @@ -186,6 +203,10 @@ fn test_markup_export_manual_ms() {
max: 2.0080,
times: Some(vec![2.0, 2.0, 2.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand All @@ -201,6 +222,10 @@ fn test_markup_export_manual_ms() {
max: 0.1080,
times: Some(vec![0.1, 0.1, 0.1]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand Down Expand Up @@ -260,6 +285,10 @@ fn test_markup_export_manual_s() {
max: 2.0080,
times: Some(vec![2.0, 2.0, 2.0]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand All @@ -275,6 +304,10 @@ fn test_markup_export_manual_s() {
max: 0.1080,
times: Some(vec![0.1, 0.1, 0.1]),
memory_usage_byte: None,
voluntary_cs: None,
involuntary_cs: None,
io_read_ops: None,
io_write_ops: None,
exit_codes: vec![Some(0), Some(0), Some(0)],
parameters: BTreeMap::new(),
},
Expand Down
Loading