From ab2c367bc1be514a7eda2c99324366d8d1c63228 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 5 Dec 2021 19:23:33 +0200 Subject: feat: collect measurements of benchmark operations Sponsored-by: author --- src/bin/obnam-benchmark.rs | 12 +++++++++++- src/lib.rs | 1 + src/result.rs | 30 +++++++++++++++++++++++++++++ src/specification.rs | 9 ++++++--- src/step.rs | 48 ++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 src/result.rs diff --git a/src/bin/obnam-benchmark.rs b/src/bin/obnam-benchmark.rs index 4d4bcf3..21012b3 100644 --- a/src/bin/obnam-benchmark.rs +++ b/src/bin/obnam-benchmark.rs @@ -1,4 +1,5 @@ use obnam_benchmark::specification::Specification; +use obnam_benchmark::result::Result; use std::fs::File; use std::path::PathBuf; use std::process::exit; @@ -42,14 +43,23 @@ struct Run { /// Name of the specification file #[structopt(parse(from_os_str))] spec: PathBuf, + + /// Name of file where the results will be written. + #[structopt(long, parse(from_os_str))] + output: PathBuf, } impl Run { fn run(&self) -> anyhow::Result<()> { let spec = Specification::from_file(&self.spec)?; + let mut result = Result::default(); for step in spec.steps() { - step.execute()?; + if let Some(m) = step.execute()? { + result.push(m); + } } + let output = File::create(&self.output)?; + serde_json::to_writer_pretty(&output, &result)?; Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 162ff87..40a8619 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,5 +28,6 @@ //! This crate only collects data from a set of benchmarks. It does //! not analyze the data. The data can be stored for later analysis. +pub mod result; pub mod specification; pub mod step; diff --git a/src/result.rs b/src/result.rs new file mode 100644 index 0000000..f5d8598 --- /dev/null +++ b/src/result.rs @@ -0,0 +1,30 @@ +use serde::Serialize; + +#[derive(Debug, Default, Serialize)] +pub struct Result { + measurements: Vec, +} + +#[derive(Debug, Serialize)] +pub struct Measurement { + op: Operation, + ms: u128, +} + +#[derive(Debug, Clone, Copy, Serialize)] +pub enum Operation { + Backup, + Restore, +} + +impl Result { + pub fn push(&mut self, m: Measurement) { + self.measurements.push(m); + } +} + +impl Measurement { + pub fn new(op: Operation, ms: u128) -> Self { + Self { op, ms } + } +} diff --git a/src/specification.rs b/src/specification.rs index c653735..2932f41 100644 --- a/src/specification.rs +++ b/src/specification.rs @@ -75,14 +75,17 @@ pub(crate) enum Change { /// How many files to create, and how big they should be. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Create { - files: u64, - file_size: u64, + /// File count. + pub files: u64, + /// Size, in bytes, of each file. + pub file_size: u64, } /// How many files to operate on. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FileCount { - files: u64, + /// File count. + pub files: u64, } impl Specification { diff --git a/src/step.rs b/src/step.rs index 35bb13b..391e7d9 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,4 +1,6 @@ +use crate::result::{Measurement, Operation}; use crate::specification::{Change, Create, FileCount}; +use std::time::Instant; /// A step in the execution of a benchmark. #[derive(Debug)] @@ -48,10 +50,48 @@ impl Step { } } - pub fn execute(&self) -> Result<(), StepError> { - println!("execute {:?}", self); - let t = std::time::Duration::from_millis(1000); + pub fn execute(&self) -> Result, StepError> { + let now = Instant::now(); + let op = match self { + Self::Start(name) => { + println!("start benchmark {}", name); + None + } + Self::Stop(name) => { + println!("stop benchmark {}", name); + None + } + Self::Create(x) => { + println!("create {} files of {} bytes", x.files, x.file_size); + None + } + Self::Rename(x) => { + println!("rename {}", x.files); + None + } + Self::Delete(x) => { + println!("delete {}", x.files); + None + } + Self::Backup(x) => { + println!("backup {}", x); + Some(Operation::Backup) + } + Self::Restore(x) => { + println!("restore {}", x); + Some(Operation::Restore) + } + }; + + let t = std::time::Duration::from_millis(10); std::thread::sleep(t); - Ok(()) + + let m = if let Some(op) = op { + let ms = now.elapsed().as_millis(); + Some(Measurement::new(op, ms)) + } else { + None + }; + Ok(m) } } -- cgit v1.2.1