From 6b273165862a2ac227646108d0cfe1b51deab65d Mon Sep 17 00:00:00 2001 From: Ethiraric Date: Fri, 15 Mar 2024 17:34:39 +0100 Subject: [PATCH] Prepare for benchmarks. --- saphyr/Cargo.toml | 4 +++ saphyr/tools/run_bench.rs | 71 ++++++++++++++++++++++++++++++++++++++ saphyr/tools/time_parse.rs | 7 +++- 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 saphyr/tools/run_bench.rs diff --git a/saphyr/Cargo.toml b/saphyr/Cargo.toml index 15425df..a87b239 100644 --- a/saphyr/Cargo.toml +++ b/saphyr/Cargo.toml @@ -35,3 +35,7 @@ path = "tools/dump_events.rs" [[bin]] name = "time_parse" path = "tools/time_parse.rs" + +[[bin]] +name = "run_bench" +path = "tools/run_bench.rs" diff --git a/saphyr/tools/run_bench.rs b/saphyr/tools/run_bench.rs new file mode 100644 index 0000000..cda9db2 --- /dev/null +++ b/saphyr/tools/run_bench.rs @@ -0,0 +1,71 @@ +#![allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)] + +use std::{env, fs::File, io::prelude::*}; +use yaml_rust2::{ + parser::{MarkedEventReceiver, Parser}, + scanner::Marker, + Event, +}; + +/// A sink which discards any event sent. +struct NullSink {} + +impl MarkedEventReceiver for NullSink { + fn on_event(&mut self, _: Event, _: Marker) {} +} + +/// Parse the given input, returning elapsed time in nanoseconds. +fn do_parse(input: &str) -> u64 { + let mut sink = NullSink {}; + let mut parser = Parser::new(input.chars()); + let begin = std::time::Instant::now(); + parser.load(&mut sink, true).unwrap(); + let end = std::time::Instant::now(); + (end - begin).as_nanos() as u64 +} + +fn main() { + let args: Vec<_> = env::args().collect(); + let iterations: u64 = args[2].parse().unwrap(); + let output_yaml = args.len() == 4 && args[3] == "--output-yaml"; + let mut f = File::open(&args[1]).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + + // Warmup + do_parse(&s); + do_parse(&s); + do_parse(&s); + + // Bench + let times: Vec<_> = (0..iterations).map(|_| do_parse(&s)).collect(); + + let mut sorted_times = times.clone(); + sorted_times.sort_unstable(); + + // Compute relevant metrics. + let sum: u64 = times.iter().sum(); + let avg = sum / iterations; + let min = sorted_times[0]; + let max = sorted_times[(iterations - 1) as usize]; + let percentile95 = sorted_times[((95 * iterations) / 100) as usize]; + + if output_yaml { + println!("parser: yaml-rust2"); + println!("input: {}", args[1]); + println!("average: {avg}"); + println!("min: {min}"); + println!("max: {max}"); + println!("percentile95: {percentile95}"); + println!("iterations: {iterations}"); + println!("times:"); + for time in × { + println!(" - {time}"); + } + } else { + println!("Average: {}s", (avg as f64) / 1_000_000_000.0); + println!("Min: {}s", (min as f64) / 1_000_000_000.0); + println!("Max: {}s", (max as f64) / 1_000_000_000.0); + println!("95%: {}s", (percentile95 as f64) / 1_000_000_000.0); + } +} diff --git a/saphyr/tools/time_parse.rs b/saphyr/tools/time_parse.rs index 9b551e1..014fcfc 100644 --- a/saphyr/tools/time_parse.rs +++ b/saphyr/tools/time_parse.rs @@ -27,5 +27,10 @@ fn main() { let begin = std::time::Instant::now(); parser.load(&mut sink, true).unwrap(); let end = std::time::Instant::now(); - println!("Loaded {}MiB in {:?}", s.len() / 1024 / 1024, end - begin); + + if args.len() == 3 && args[2] == "--short" { + println!("{}", (end - begin).as_nanos()); + } else { + println!("Loaded {}MiB in {:?}", s.len() / 1024 / 1024, end - begin); + } }