From dce57e6332d3de458309b1f33377601cbe3f603e Mon Sep 17 00:00:00 2001 From: Aristotelis Papanis Date: Thu, 13 Mar 2025 14:13:54 +0200 Subject: chore(metrics): Change output format of metrics We have improved the format of the benchmarking output. Now the metrics follow a more standard CSV style. Example: ``` name,guest,total duration,repeats,average jolt,fibonacci,1.33,2,0.516 nexus,fibonacci,177.388,2,88.694 risc0,fibonacci,3.828,2,1.914 sp1,fibonacci,13.330,2,6.665 zkm,fibonacci,279.394,2,139.697 zkwasm,fibonacci,106.161,2,53.80 ``` --- zkvms_host_io/input_macros/src/lib.rs | 61 +++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/zkvms_host_io/input_macros/src/lib.rs b/zkvms_host_io/input_macros/src/lib.rs index 60d3d48..6ef2e7c 100644 --- a/zkvms_host_io/input_macros/src/lib.rs +++ b/zkvms_host_io/input_macros/src/lib.rs @@ -198,10 +198,11 @@ pub fn foreach_private_input_field(item: TokenStream) -> TokenStream { pub fn benchmarkable(item: TokenStream) -> TokenStream { format!(r#" {{ - use std::time::Instant; + use std::time::{{Duration, Instant}}; use std::fs::OpenOptions; use std::io::Write; - + use std::path::Path; + let mut starts = Vec::new(); let mut ends = Vec::new(); @@ -218,28 +219,54 @@ pub fn benchmarkable(item: TokenStream) -> TokenStream { }} if run_info.benchmarking {{ - let mut output = format!("zkvm,{{}}\nguest,{{}}\n", env!("ZKVM"), env!("GUEST")); + let info_row = format!("name,guest,total duration,repeats,average\n"); + let mut output = format!("{{}},{{}},", env!("ZKVM"), env!("GUEST")); let duration = *ends.last().unwrap() - *starts.first().unwrap(); - let duration = if run_info.millis {{ duration.as_millis() }} else {{ duration.as_secs().into() }}; - output += &format!("duration,{{duration}}\n"); - + if run_info.millis {{ + output += &format!("{{}},", duration.as_millis()); + }} else {{ + output += &format!("{{}}.{{}},", duration.as_secs(), duration.subsec_millis()); + }} + let durations = starts .into_iter() .zip(ends.into_iter()) - .map(|(s,e)| if run_info.millis {{ (e - s).as_millis() }} else {{ (e - s).as_secs().into() }}) - .collect::>(); - let average = durations.iter().sum::() / durations.len() as u128; - output += &format!("repeats,{{}}\naverage,{{average}}\n", run_info.repeats); + .map(|(s,e)| e - s ) + .collect::>(); + let average = durations.iter().sum::() / durations.len() as u32; + + if run_info.millis {{ + output += &format!("{{}},{{}}\n", run_info.repeats, average.as_millis()); + }} else {{ + output += &format!("{{}},{{}}.{{}}\n", run_info.repeats, average.as_secs(), average.subsec_millis()); + }} if let Some(file) = run_info.output_file {{ - let mut outfile = OpenOptions::new() - .write(true) - .create(true) - .append(run_info.append) - .open(file) - .unwrap(); - write!(outfile, "{{}}", output); + + let file_exists = Path::new(&file).exists(); + + let mut outfile = match OpenOptions::new() + .write(true) + .create(true) + .append(run_info.append) + .open(&file) + {{ + Ok(file) => file, + Err(e) => {{ + panic!("Failed to open file: {{}}", e); + }} + }}; + + if !file_exists {{ + if let Err(e) = write!(outfile, "{{}}", info_row) {{ + panic!("Failed to write info_row: {{}}", e); + }} + }} + + if let Err(e) = write!(outfile, "{{}}", output) {{ + panic!("Failed to write output: {{}}", e); + }} }} else {{ print!("{{}}", output); -- cgit v1.2.3