1use std::time::Instant;
2
3pub struct TimeSpan {
17 name: &'static str,
18 start: Instant,
19}
20
21impl TimeSpan {
22 pub fn new(name: &'static str) -> Self {
24 Self {
25 name,
26 start: Instant::now(),
27 }
28 }
29}
30
31impl Drop for TimeSpan {
32 fn drop(&mut self) {
33 let elapsed = self.start.elapsed();
34 log::info!(
35 "[TIME] {} took {:.3} ms",
36 self.name,
37 elapsed.as_secs_f64() * 1000.0
38 );
39 }
40}
41
42#[macro_export]
54macro_rules! time_span {
55 ($name:expr) => {
56 let _time_span_guard = $crate::TimeSpan::new($name);
57 };
58}
59
60pub fn measure_time<T, F>(name: &str, mut f: F) -> T
71where
72 F: FnMut() -> T,
73{
74 let start = Instant::now();
75 let result = f();
76 let elapsed = start.elapsed();
77 log::info!(
78 "[TIME] {} took {:.3} ms",
79 name,
80 elapsed.as_secs_f64() * 1000.0
81 );
82 result
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use std::thread;
89 use std::time::Duration;
90
91 #[test]
92 fn test_time_span_new() {
93 let _span = TimeSpan::new("test_span");
94 }
95
96 #[test]
97 fn test_time_span_drop() {
98 {
99 let _span = TimeSpan::new("drop_test");
100 }
101 }
102
103 #[test]
104 fn test_measure_time_basic() {
105 let result = measure_time("basic_test", || 42);
106 assert_eq!(result, 42);
107 }
108
109 #[test]
110 fn test_measure_time_with_sleep() {
111 let result = measure_time("sleep_test", || {
112 thread::sleep(Duration::from_millis(10));
113 "done"
114 });
115 assert_eq!(result, "done");
116 }
117
118 #[test]
119 fn test_measure_time_with_return() {
120 let result = measure_time("return_test", || {
121 let x = 10;
122 let y = 20;
123 x + y
124 });
125 assert_eq!(result, 30);
126 }
127
128 #[test]
129 fn test_macro_basic() {
130 time_span!("macro_test");
131 }
132
133 #[test]
134 fn test_macro_in_function() {
135 fn test_func() {
136 time_span!("func_test");
137 assert!(true);
138 }
139 test_func();
140 }
141
142 #[test]
143 fn test_multiple_spans() {
144 {
145 let _span1 = TimeSpan::new("span1");
146 {
147 let _span2 = TimeSpan::new("span2");
148 }
149 }
150 }
151
152 #[test]
153 fn test_nested_measure_time() {
154 let result = measure_time("outer", || measure_time("inner", || 100));
155 assert_eq!(result, 100);
156 }
157
158 #[test]
159 fn test_measure_time_with_mut() {
160 let mut count = 0;
161 let result = measure_time("mut_test", || {
162 count += 1;
163 count
164 });
165 assert_eq!(result, 1);
166 assert_eq!(count, 1);
167 }
168}