mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-10-28 08:08:58 +00:00
Document JSON measurements and omit unavailable memory metrics
This commit is contained in:
1 parent
21bbcc5490
commit
4cd0e24586
9 files changed
+147
-44
No files matched your search
@@ -277,7 +277,7 @@ impl Executor for ShellExecutor<'_> {
|
||||
time_wall_clock: measurements.time_wall_clock_mean(),
|
||||
time_user: measurements.time_user_mean(),
|
||||
time_system: measurements.time_system_mean(),
|
||||
peak_memory_usage: measurements.peak_memory_usage_mean(),
|
||||
peak_memory_usage: None,
|
||||
exit_status: ExitStatus::default(),
|
||||
});
|
||||
|
||||
@@ -335,7 +335,7 @@ impl Executor for MockExecutor {
|
||||
time_wall_clock: Self::extract_time(command.get_command_line()),
|
||||
time_user: Time::zero(),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::zero(),
|
||||
peak_memory_usage: Some(Information::zero()),
|
||||
exit_status,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_optional_information<S>(
|
||||
value: &Option<Information>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match value {
|
||||
Some(value) => serialize_information(value, serializer),
|
||||
None => serializer.serialize_none(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Performance metric measurements and exit code for a single run
|
||||
#[derive(Debug, Clone, Default, Serialize, PartialEq)]
|
||||
pub struct Measurement {
|
||||
@@ -31,9 +44,12 @@ pub struct Measurement {
|
||||
#[serde(serialize_with = "serialize_time")]
|
||||
pub time_system: Time,
|
||||
|
||||
/// Maximum memory usage of the process
|
||||
#[serde(serialize_with = "serialize_information")]
|
||||
pub peak_memory_usage: Information,
|
||||
/// Peak resident set size, if available on this platform
|
||||
#[serde(
|
||||
skip_serializing_if = "Option::is_none",
|
||||
serialize_with = "serialize_optional_information"
|
||||
)]
|
||||
pub peak_memory_usage: Option<Information>,
|
||||
|
||||
// The exit status of the process
|
||||
#[serde(rename = "exit_code", serialize_with = "serialize_exit_status")]
|
||||
@@ -111,8 +127,4 @@ impl Measurements {
|
||||
pub fn time_system_mean(&self) -> Time {
|
||||
mean(self.measurements.iter().map(|m| m.time_system))
|
||||
}
|
||||
|
||||
pub fn peak_memory_usage_mean(&self) -> Information {
|
||||
mean(self.measurements.iter().map(|m| m.peak_memory_usage))
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -86,21 +86,21 @@ fn test_csv() {
|
||||
time_wall_clock: Time::new::<second>(7.0),
|
||||
time_user: Time::new::<second>(7.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(8.0),
|
||||
time_user: Time::new::<second>(8.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(12.0),
|
||||
time_user: Time::new::<second>(12.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -130,21 +130,21 @@ fn test_csv() {
|
||||
time_wall_clock: Time::new::<second>(17.0),
|
||||
time_user: Time::new::<second>(17.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(18.0),
|
||||
time_user: Time::new::<second>(18.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(19.0),
|
||||
time_user: Time::new::<second>(19.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
|
||||
@@ -32,3 +32,50 @@ impl Exporter for JsonExporter {
|
||||
Ok(output?)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_optional_memory() {
|
||||
use crate::benchmark::measurement::{Measurement, Measurements};
|
||||
use crate::quantity::{byte, Information};
|
||||
use serde_json::json;
|
||||
|
||||
for (memory, expected_memory) in [
|
||||
(None, None),
|
||||
(
|
||||
Some(Information::new::<byte>(0.0)),
|
||||
Some(json!({"value": 0.0, "unit": "byte"})),
|
||||
),
|
||||
(
|
||||
Some(Information::new::<byte>(1024.0)),
|
||||
Some(json!({"value": 1024.0, "unit": "byte"})),
|
||||
),
|
||||
] {
|
||||
let result = BenchmarkResult {
|
||||
command: "example".into(),
|
||||
measurements: Measurements::new(vec![Measurement {
|
||||
peak_memory_usage: memory,
|
||||
..Measurement::default()
|
||||
}]),
|
||||
..BenchmarkResult::default()
|
||||
};
|
||||
let output = JsonExporter::default()
|
||||
.serialize(&[result], None, SortOrder::Command)
|
||||
.unwrap();
|
||||
let actual: serde_json::Value = serde_json::from_slice(&output).unwrap();
|
||||
let mut expected = json!({
|
||||
"results": [{
|
||||
"command": "example",
|
||||
"measurements": [{
|
||||
"time_wall_clock": {"value": 0.0, "unit": "second"},
|
||||
"time_user": {"value": 0.0, "unit": "second"},
|
||||
"time_system": {"value": 0.0, "unit": "second"},
|
||||
"exit_code": 0
|
||||
}]
|
||||
}]
|
||||
});
|
||||
if let Some(memory) = expected_memory {
|
||||
expected["results"][0]["measurements"][0]["peak_memory_usage"] = memory;
|
||||
}
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
+24
-24
@@ -33,21 +33,21 @@ fn test_markup_export_auto_ms() {
|
||||
time_wall_clock: Time::new::<second>(0.09),
|
||||
time_user: Time::new::<second>(0.09),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.10),
|
||||
time_user: Time::new::<second>(0.10),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.14),
|
||||
time_user: Time::new::<second>(0.14),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -60,21 +60,21 @@ fn test_markup_export_auto_ms() {
|
||||
time_wall_clock: Time::new::<second>(2.0),
|
||||
time_user: Time::new::<second>(2.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(3.0),
|
||||
time_user: Time::new::<second>(3.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(4.0),
|
||||
time_user: Time::new::<second>(4.0),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -132,21 +132,21 @@ fn test_markup_export_auto_s() {
|
||||
time_wall_clock: Time::new::<second>(2.1),
|
||||
time_user: Time::new::<second>(2.1),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.2),
|
||||
time_user: Time::new::<second>(2.2),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.3),
|
||||
time_user: Time::new::<second>(2.3),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -159,21 +159,21 @@ fn test_markup_export_auto_s() {
|
||||
time_wall_clock: Time::new::<second>(0.1),
|
||||
time_user: Time::new::<second>(0.1),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.2),
|
||||
time_user: Time::new::<second>(0.2),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.3),
|
||||
time_user: Time::new::<second>(0.3),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -231,21 +231,21 @@ fn test_markup_export_manual_ms() {
|
||||
time_wall_clock: Time::new::<second>(2.1),
|
||||
time_user: Time::new::<second>(2.1),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.2),
|
||||
time_user: Time::new::<second>(2.2),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.3),
|
||||
time_user: Time::new::<second>(2.3),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -258,21 +258,21 @@ fn test_markup_export_manual_ms() {
|
||||
time_wall_clock: Time::new::<second>(0.1),
|
||||
time_user: Time::new::<second>(0.1),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.2),
|
||||
time_user: Time::new::<second>(0.2),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.3),
|
||||
time_user: Time::new::<second>(0.3),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -329,21 +329,21 @@ fn test_markup_export_manual_s() {
|
||||
time_wall_clock: Time::new::<second>(2.01),
|
||||
time_user: Time::new::<second>(2.01),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.02),
|
||||
time_user: Time::new::<second>(2.02),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(2.03),
|
||||
time_user: Time::new::<second>(2.03),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
@@ -356,21 +356,21 @@ fn test_markup_export_manual_s() {
|
||||
time_wall_clock: Time::new::<second>(0.11),
|
||||
time_user: Time::new::<second>(0.11),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.12),
|
||||
time_user: Time::new::<second>(0.12),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
Measurement {
|
||||
time_wall_clock: Time::new::<second>(0.13),
|
||||
time_user: Time::new::<second>(0.13),
|
||||
time_system: Time::zero(),
|
||||
peak_memory_usage: Information::new::<byte>(1024.),
|
||||
peak_memory_usage: Some(Information::new::<byte>(1024.)),
|
||||
exit_status: ExitStatus::default(),
|
||||
},
|
||||
]),
|
||||
|
||||
@@ -77,12 +77,12 @@ impl CPUTimer {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub fn stop(&self, child: Child) -> Result<(Time, Time, Information, ExitStatus)> {
|
||||
pub fn stop(&self, child: Child) -> Result<(Time, Time, Option<Information>, ExitStatus)> {
|
||||
let (status, usage) = wait4(child)?;
|
||||
Ok((
|
||||
usage.time_user,
|
||||
usage.time_system,
|
||||
usage.memory_usage,
|
||||
Some(usage.memory_usage),
|
||||
status,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ impl CPUTimer {
|
||||
Self { job_object }
|
||||
}
|
||||
|
||||
pub fn stop(&self, mut child: Child) -> Result<(Time, Time, Information, ExitStatus)> {
|
||||
pub fn stop(&self, mut child: Child) -> Result<(Time, Time, Option<Information>, ExitStatus)> {
|
||||
let status = child.wait()?;
|
||||
|
||||
let mut job_object_info =
|
||||
@@ -116,9 +116,9 @@ impl CPUTimer {
|
||||
let system_time =
|
||||
Time::new::<nanosecond>((job_object_info.TotalKernelTime as f64) * 100.0);
|
||||
|
||||
Ok((user_time, system_time, Information::zero(), status))
|
||||
Ok((user_time, system_time, None, status))
|
||||
} else {
|
||||
Ok((Time::zero(), Time::zero(), Information::zero(), status))
|
||||
Ok((Time::zero(), Time::zero(), None, status))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user