Last active
August 14, 2022 11:46
-
-
Save gre/9872e000f88294830dfb89e63d8ea236 to your computer and use it in GitHub Desktop.
Very simple helpers to record performance
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
use instant::Instant; | |
use serde::ser::SerializeStruct; | |
use serde::{Serialize}; | |
use std::collections::HashMap; | |
// Helpers for measuring performance | |
struct Span { | |
label: String, | |
start: Instant, | |
stop: Instant, | |
} | |
struct PerfRecords { | |
initial: Instant, | |
started: HashMap<String, Instant>, | |
spans: Vec<Span>, | |
} | |
// synthetic summary of time elapsed in seconds | |
struct PerfResult { | |
total: f64, | |
per_label: HashMap<String, f64>, | |
} | |
impl PerfRecords { | |
/** | |
* let mut perf = PerfRecords::start(); | |
*/ | |
pub fn start() -> Self { | |
let initial = Instant::now(); | |
PerfRecords { | |
initial, | |
started: HashMap::new(), | |
spans: Vec::new(), | |
} | |
} | |
/** | |
* perf.span("calc_circles"); | |
*/ | |
pub fn span(self: &mut Self, s: &str) { | |
self.started.insert(String::from(s), Instant::now()); | |
} | |
/** | |
* perf.span_end("calc_circles"); | |
*/ | |
pub fn span_end(self: &mut Self, s: &str) { | |
let label = String::from(s); | |
if let Some(&start) = self.started.get(&label) { | |
self.spans.push(Span { | |
label, | |
start, | |
stop: Instant::now(), | |
}); | |
} | |
} | |
/** | |
* let perf_res = perf.end(); | |
*/ | |
pub fn end(self: &Self) -> PerfResult { | |
let mut per_label = HashMap::new(); | |
let total = self.initial.elapsed().as_secs_f64(); | |
self.spans.iter().for_each(|span| { | |
let maybe_time = | |
per_label.get(&span.label).unwrap_or(&0.); | |
per_label.insert( | |
span.label.clone(), | |
maybe_time | |
+ span | |
.stop | |
.duration_since(span.start) | |
.as_secs_f64(), | |
); | |
}); | |
PerfResult { total, per_label } | |
} | |
} | |
impl Serialize for PerfResult { | |
fn serialize<S>( | |
&self, | |
serializer: S, | |
) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
let mut state = | |
serializer.serialize_struct("Perf", 2)?; | |
state.serialize_field("total", &self.total)?; | |
state.serialize_field("per_label", &self.per_label)?; | |
state.end() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment