pub use std::{sync::Mutex, time::Duration};
pub use cpu_time::ProcessTime;
pub use dashmap::DashMap;
pub use lazy_static::lazy_static;
lazy_static! {
pub static ref cpu_times: dashmap::DashMap<String, (usize, Duration)> = DashMap::new();
pub static ref enabled: Mutex<bool> = Mutex::new(false);
pub static ref overhead_time: Mutex<Vec<Duration>> = Mutex::new(Vec::new());
}
pub fn start() {
let mut e = enabled.try_lock().unwrap();
*e = true;
}
pub fn stop() {
let mut e = enabled.try_lock().unwrap();
*e = false;
*overhead_time.lock().unwrap() = Vec::new();
}
pub fn show() {
cpu_times.clone().into_iter().for_each(|(s, (count, dur))| {
println!(
"{: <24}: {: <10} calls | {: <10} total ms",
s,
count,
dur.as_micros() as f64 / 1000.0,
)
})
}
#[macro_export]
macro_rules! trace_cpu {
( $name: literal, $x:expr ) => {{
let now = ProcessTime::now();
if !*enabled.lock().unwrap() {
return $x;
}
if !cpu_times.contains_key($name) {
cpu_times.insert($name.to_string(), (0, Duration::from_millis(0)));
}
overhead_time
.lock()
.unwrap()
.push(now.try_elapsed().unwrap());
let ret = $x;
let elapsed = now.try_elapsed().unwrap();
let mut vec = overhead_time.lock().unwrap();
let top = vec.pop().unwrap();
let mut tpl = cpu_times.get_mut($name).unwrap();
(*tpl).0 += 1;
(*tpl).1 += elapsed - top;
let new_vec = vec.clone();
let total_time = now.try_elapsed().unwrap();
*vec = new_vec
.into_iter()
.map(|t| t + total_time - elapsed + Duration::from_nanos(800))
.collect::<Vec<_>>();
ret
}};
}