testudo/src/timer.rs
src/timer.rsRaw
1/// Timer is a simple utility to profile the execution time of a block of code.
2#[cfg(feature = "profile")]
3use colored::Colorize;
4#[cfg(feature = "profile")]
5use core::sync::atomic::AtomicUsize;
6#[cfg(feature = "profile")]
7use core::sync::atomic::Ordering;
8#[cfg(feature = "profile")]
9use std::time::Instant;
10
11#[cfg(feature = "profile")]
12pub static CALL_DEPTH: AtomicUsize = AtomicUsize::new(0);
13
14#[cfg(feature = "profile")]
15pub struct Timer {
16 label: String,
17 timer: Instant,
18}
19
20#[cfg(feature = "profile")]
21impl Timer {
22 #[inline(always)]
23 pub fn new(label: &str) -> Self {
24 let timer = Instant::now();
25 CALL_DEPTH.fetch_add(1, Ordering::Relaxed);
26 let star = "* ";
27 println!(
28 "{:indent$}{}{}",
29 "",
30 star,
31 label.yellow().bold(),
32 indent = 2 * CALL_DEPTH.fetch_add(0, Ordering::Relaxed)
33 );
34 Self {
35 label: label.to_string(),
36 timer,
37 }
38 }
39
40 #[inline(always)]
41 pub fn stop(&self) {
42 let duration = self.timer.elapsed();
43 let star = "* ";
44 println!(
45 "{:indent$}{}{} {:?}",
46 "",
47 star,
48 self.label.blue().bold(),
49 duration,
50 indent = 2 * CALL_DEPTH.fetch_add(0, Ordering::Relaxed)
51 );
52 CALL_DEPTH.fetch_sub(1, Ordering::Relaxed);
53 }
54
55 #[inline(always)]
56 pub fn print(msg: &str) {
57 CALL_DEPTH.fetch_add(1, Ordering::Relaxed);
58 let star = "* ";
59 println!(
60 "{:indent$}{}{}",
61 "",
62 star,
63 msg.to_string().green().bold(),
64 indent = 2 * CALL_DEPTH.fetch_add(0, Ordering::Relaxed)
65 );
66 CALL_DEPTH.fetch_sub(1, Ordering::Relaxed);
67 }
68}
69
70#[cfg(not(feature = "profile"))]
71pub struct Timer {
72 _label: String,
73}
74
75#[cfg(not(feature = "profile"))]
76impl Timer {
77 #[inline(always)]
78 pub fn new(label: &str) -> Self {
79 Self {
80 _label: label.to_string(),
81 }
82 }
83
84 #[inline(always)]
85 pub fn stop(&self) {}
86
87 #[inline(always)]
88 pub fn print(_msg: &str) {}
89}