-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
134 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
mod bencher; | ||
pub mod probe; | ||
mod record; | ||
pub mod utils; | ||
|
||
pub use bencher::{BenchTimer, Bencher, Value}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
use std::io::Write; | ||
use std::{collections::HashMap, fs::OpenOptions, path::PathBuf}; | ||
|
||
use clap::ValueEnum; | ||
|
||
use crate::Value; | ||
|
||
#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] | ||
#[clap(rename_all = "kebab_case")] | ||
pub(crate) enum StatPrintFormat { | ||
Table, | ||
Yaml, | ||
} | ||
|
||
pub(crate) struct Record<'a> { | ||
pub name: &'a str, | ||
pub csv: Option<&'a PathBuf>, | ||
pub invocation: Option<usize>, | ||
pub build: Option<&'a String>, | ||
pub format: StatPrintFormat, | ||
pub iteration: usize, | ||
pub is_timing_iteration: bool, | ||
pub stats: HashMap<String, Box<dyn Value>>, | ||
} | ||
|
||
impl<'a> Record<'a> { | ||
fn dump_counters_stderr_table(&self, stats: &[(String, Box<dyn Value>)]) { | ||
for (name, _) in stats { | ||
eprint!("{}\t", name); | ||
} | ||
eprintln!(); | ||
for (_, value) in stats { | ||
eprint!("{}\t", value.to_string()); | ||
} | ||
eprintln!(); | ||
} | ||
|
||
fn dump_counters_stderr_yaml(&self, stats: &[(String, Box<dyn Value>)]) { | ||
for (name, value) in stats { | ||
eprintln!("{}: {}", name, value.to_string()); | ||
} | ||
} | ||
|
||
fn dump_counters_stderr(&self, stats: &[(String, Box<dyn Value>)], format: StatPrintFormat) { | ||
let force_table = std::env::var("HARNESS_LOG_STAT_FORMAT") == Ok("table".to_owned()); | ||
if force_table { | ||
return self.dump_counters_stderr_table(stats); | ||
} | ||
match format { | ||
StatPrintFormat::Table => self.dump_counters_stderr_table(stats), | ||
StatPrintFormat::Yaml => self.dump_counters_stderr_yaml(stats), | ||
} | ||
} | ||
|
||
fn dump_counters_csv(&self, stats: &[(String, Box<dyn Value>)]) { | ||
if let Some(csv) = self.csv { | ||
if !csv.exists() { | ||
let mut headers = "bench,build,invocation,iteration".to_owned(); | ||
for (name, _value) in stats { | ||
headers += ","; | ||
headers += name; | ||
} | ||
headers += "\n"; | ||
std::fs::write(csv, headers).unwrap(); | ||
} | ||
let mut record = format!( | ||
"{},{},{},{}", | ||
self.name, | ||
self.build.unwrap(), | ||
self.invocation.unwrap_or(0), | ||
self.iteration | ||
); | ||
for (_, value) in stats { | ||
record += &format!(",{}", value.to_string()); | ||
} | ||
let mut csv = OpenOptions::new().append(true).open(csv).unwrap(); | ||
writeln!(csv, "{record}").unwrap(); | ||
} | ||
} | ||
|
||
pub fn dump_values(mut self) { | ||
let mut stats_map = std::mem::take(&mut self.stats); | ||
let time = stats_map.remove("time"); | ||
let mut stats: Vec<(String, Box<dyn Value>)> = vec![]; | ||
for (name, value) in stats_map { | ||
stats.push((name.clone(), value)); | ||
} | ||
stats.sort_by_key(|x| x.0.clone()); | ||
if let Some(time) = time { | ||
stats.insert(0, ("time".to_owned(), time)); | ||
} | ||
if self.is_timing_iteration { | ||
// Print to the log file | ||
let banner_start = std::env::var("HARNESS_LOG_STAT_BANNER_START").unwrap_or_else(|_| { | ||
"============================ Harness Statistics Totals ============================".to_string() | ||
}); | ||
eprintln!("{banner_start}"); | ||
self.dump_counters_stderr(&stats, self.format); | ||
let banner_end = std::env::var("HARNESS_LOG_STAT_BANNER_END").unwrap_or_else(|_| { | ||
"------------------------------ End Harness Statistics -----------------------------".to_string() | ||
}); | ||
eprintln!("{banner_end}"); | ||
} | ||
// Print to the CSV file | ||
self.dump_counters_csv(&stats); | ||
} | ||
} |