pub struct Perf {
start: std::time::Instant,
start_line: String,
ident: String,
lap: Option<std::time::Instant>,
lap_n: Option<usize>,
}
impl Perf {
pub fn new(ident: String, start_line: String) -> Self {
Perf {
start: std::time::Instant::now(),
start_line,
ident,
lap: None,
lap_n: None,
}
}
pub fn lap(&mut self, msg: &str) {
let base = match self.lap {
Some(l) => l,
None => self.start,
};
let lap_n = self.lap_n.unwrap_or(1);
let elapsed = base.elapsed();
if cfg!(all(target_os = "windows", not(debug_assertions))) {
eprintln!(
"{}.{} ({} - {} - lap {})",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
msg,
lap_n,
);
} else {
eprintln!(
"\x1B[33m\x1B[1m{}.{} ({} - {} - lap {})\x1B[0m",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
msg,
lap_n,
);
}
self.lap = Some(std::time::Instant::now());
self.lap_n = Some(lap_n + 1);
}
pub fn split(&self, msg: &str) {
let elapsed = self.start.elapsed();
if cfg!(all(target_os = "windows", not(debug_assertions))) {
eprintln!(
"{}.{} ({} - {})",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
msg,
);
} else {
eprintln!(
"\x1B[33m\x1B[1m{}.{} ({} - {})\x1B[0m",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
msg
);
}
}
pub fn end(self) {
let elapsed = self.start.elapsed();
if cfg!(all(target_os = "windows", not(debug_assertions))) {
eprintln!(
"{}.{} ({} - end) @ {}",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
self.start_line,
);
} else {
eprintln!(
"\x1B[33m\x1B[1m{}.{} ({} - end)\x1B[0m @ {}",
elapsed.as_secs(),
format!("{:09}", elapsed.subsec_nanos()),
self.ident,
self.start_line,
);
}
}
}
#[macro_export]
macro_rules! perf {
($val:expr) => {
match $val {
i => {
let ident = format!("{}", i);
let start_line = format!("[{}:{}]", file!(), line!());
Perf::new(ident, start_line)
}
}
};
}
#[cfg(test)]
mod tests {
use super::*;
fn add(a: i32, b: i32) -> i32 {
std::thread::sleep(std::time::Duration::from_millis(100));
a + b
}
#[test]
fn basic_example() {
let p = perf!("add fn");
let _result = add(4, 4);
p.end();
}
#[test]
fn split_test() {
let p = perf!("add fn");
let _result = add(4, 4);
p.split("add");
let _div = _result / 2;
p.split("div");
p.end();
}
#[test]
fn lap_test() {
let mut p = perf!("add fn");
let _result = add(4, 4);
p.lap("add");
let _div = _result / 2;
p.lap("div");
p.end();
}
fn add_fast(a: i32, b: i32) -> i32 {
a + b
}
#[test]
fn fast_example() {
let p = perf!("add fn");
let _result = add_fast(4, 4);
p.end();
}
}