gravel_core/
performance.rs1use log::Level;
2use std::fmt::{self, Arguments, Display, Formatter};
3use std::time::Instant;
4
5#[derive(Debug)]
6pub struct Stopwatch {
7 begin: Instant,
8}
9
10impl Stopwatch {
11 pub fn start() -> Self {
12 Self { begin: Instant::now() }
13 }
14}
15
16impl Display for Stopwatch {
17 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
18 let micros = self.begin.elapsed().as_micros() as f32;
20 let millis = micros / 1000.0;
21 write!(f, "{millis}ms")
22 }
23}
24
25#[derive(Debug)]
26pub struct Timed {
27 message: String,
28 level: Level,
29 stopwatch: Stopwatch,
30}
31
32impl Timed {
33 pub fn new(level: Level, args: Arguments<'_>) -> Option<Self> {
34 if level > log::STATIC_MAX_LEVEL || level > log::max_level() {
35 return None;
36 }
37
38 Some(Self {
39 message: args.to_string(),
40 level,
41 stopwatch: Stopwatch::start(),
42 })
43 }
44}
45
46impl Drop for Timed {
47 fn drop(&mut self) {
48 log::log!(self.level, "{} {}", self.message, self.stopwatch);
49 }
50}
51
52#[macro_export]
53macro_rules! timed {
54 ( ($($arg:tt)*), $body:block ) => { timed!(::log::Level::Trace, ::std::format_args!($($arg)*), $body) };
55 ( $msg:literal, $body:block ) => { timed!(::log::Level::Trace, ::std::format_args!($msg), $body) };
56 ( $level:expr, ($($arg:tt)*), $body:block ) => { timed!($level, ::std::format_args!($($arg)*), $body) };
57 ( $level:expr, $msg:literal, $body:block ) => { timed!($level, ::std::format_args!($msg), $body) };
58
59 ( $level:expr, $msg:expr, $body:block ) => {{
60 let __time = $crate::performance::Timed::new($level, $msg);
61
62 $body
63 }};
64}