timelapse/
profiler.rs

1//! A simple profiler for measuring elapsed time in Rust.
2//!
3//! This module provides a `TimeLapse` struct and macros to start and end profiling.
4//! Macros `profile_start!` and `profile_end!` are used to simplify the profiling process.
5//!
6//! See the tesing examples at the end of this source file for usage.
7
8#![allow(unused)]
9use log::info;
10use std::time::{Duration, Instant};
11
12/// The `profile_start!` macro initializes a `TimeLapse` instance to start profiling.
13/// It takes an identifier as an argument, which will be used to reference the profiler instance.
14#[macro_export]
15macro_rules! profile_start {
16    ($name:ident) => {
17        let $name = TimeLapse::new();
18    };
19}
20
21/// The `profile_end!` macro logs the elapsed time of the profiling instance created by `profile_start!`.
22/// These macros are useful for quick profiling without needing to manually create and manage `TimeLapse` instances.
23#[macro_export]
24macro_rules! profile_end {
25    ($name:ident) => {
26        $name.log(stringify!($name));
27    };
28}
29
30/// The `TimeLapse` struct is used to measure elapsed time in Rust applications.
31/// It provides methods to start, reset, and log the elapsed time.
32/// It can be used to profile code execution and is useful for performance analysis.
33/// It implements the `Display` and `Debug` traits for easy formatting and logging.
34pub struct TimeLapse {
35    start_time: Instant,
36}
37
38impl TimeLapse {
39    /// Creates a new `TimeLapse` instance, starting the timer immediately.
40    pub fn new() -> Self {
41        TimeLapse {
42            start_time: Instant::now(),
43        }
44    }
45
46    /// Returns the elapsed time since the `TimeLapse` instance was created or reset.
47    pub fn elapsed(&self) -> Duration {
48        self.start_time.elapsed()
49    }
50
51    /// Resets the timer, starting a new measurement from the current time.
52    pub fn reset(&mut self) {
53        self.start_time = Instant::now();
54    }
55}
56
57/// Implements the `Display` trait for the `TimeLapse` struct.
58impl std::fmt::Display for TimeLapse {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(f, "Elapsed time: {:?}", self.elapsed())
61    }
62}
63
64/// Implements the `Debug` trait for the `TimeLapse` struct.
65impl std::fmt::Debug for TimeLapse {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "TimeLapse {{ elapsed: {:?} }}", self.elapsed())
68    }
69}
70
71/// Implements the `Default` trait for the `TimeLapse` struct, allowing it to be created with default values.
72impl std::default::Default for TimeLapse {
73    fn default() -> Self {
74        Self::new()
75    }
76}
77
78impl TimeLapse {
79    /// Logs the elapsed time with a given name.
80    pub fn log(&self, name: &str) {
81        info!("TimeLapse {} - Elapsed time: {:?}", name, self.elapsed());
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_profiler() {
91        let profiler = TimeLapse::new();
92        std::thread::sleep(Duration::from_millis(100));
93        assert!(profiler.elapsed().as_millis() >= 100);
94        profiler.log("test");
95    }
96
97    #[test]
98    fn test_profiler_macros() {
99        profile_start!(the_profile);
100        std::thread::sleep(Duration::from_millis(100));
101        assert!(the_profile.elapsed().as_millis() >= 100);
102        profile_end!(the_profile);
103    }
104
105    #[test]
106    fn test_profiler_reset() {
107        let mut profiler = TimeLapse::new();
108        std::thread::sleep(Duration::from_millis(100));
109        profiler.reset();
110        assert!(profiler.elapsed().as_millis() < 50);
111    }
112}