#[macro_export]
macro_rules! dbg_time {
($id:expr, $x:expr) => {{
let now = std::time::Instant::now();
let result = $x;
let elapsed = now.elapsed();
print!("{}: ", $id);
if elapsed < std::time::Duration::from_nanos(1000) {
println!("{} ns", elapsed.as_nanos());
} else if elapsed < std::time::Duration::from_micros(1000) {
println!("{:.2} μs", elapsed.as_nanos() as f64 / 1000.0);
} else if elapsed < std::time::Duration::from_millis(1000) {
println!("{:.2} ms", elapsed.as_micros() as f64 / 1000.0);
} else {
println!("{:.2} s", elapsed.as_millis() as f64 / 1000.0);
}
result
}};
}
#[macro_export]
macro_rules! time {
($x:expr) => {{
let now = std::time::Instant::now();
let _result = $x;
now.elapsed()
}};
}
#[cfg(test)]
mod tests {
use super::*;
use std::hint::black_box;
#[test]
fn time_is_nonzero() {
let time = time!({
let mut sum: i32 = black_box(0);
for i in 0..1_000 {
sum = sum.wrapping_add(i);
}
});
assert!(!time.is_zero());
}
#[test]
fn time_returns_rational_duration() {
let duration = time!({
std::thread::sleep(std::time::Duration::from_millis(1));
});
assert!(duration >= std::time::Duration::from_millis(1));
assert!(duration < std::time::Duration::from_millis(100));
}
#[test]
fn dbg_time_returns_value() {
let value = dbg_time!("computation", { 5 * 10 });
assert_eq!(value, 50);
}
}