scirs2_core/profiling/
timer.rs1use crate::profiling::profiler::Profiler;
4use std::time::{Duration, Instant};
5
6pub struct Timer {
8 name: String,
10 start_time: Instant,
12 running: bool,
14 auto_report: bool,
16 parent: Option<String>,
18}
19
20impl Timer {
21 pub fn start(name: &str) -> Self {
23 let timer = Self {
24 name: name.to_string(),
25 start_time: Instant::now(),
26 running: true,
27 auto_report: true,
28 parent: None,
29 };
30 if let Ok(mut profiler) = Profiler::global().lock() {
31 profiler.register_timer_start(&timer);
32 }
33 timer
34 }
35
36 pub fn start_with_parent(name: &str, parent: &str) -> Self {
38 let timer = Self {
39 name: name.to_string(),
40 start_time: Instant::now(),
41 running: true,
42 auto_report: true,
43 parent: Some(parent.to_string()),
44 };
45 if let Ok(mut profiler) = Profiler::global().lock() {
46 profiler.register_timer_start(&timer);
47 }
48 timer
49 }
50
51 pub fn time_function<F, R>(name: &str, f: F) -> R
53 where
54 F: FnOnce() -> R,
55 {
56 let timer = Self::start(name);
57 let result = f();
58 timer.stop();
59 result
60 }
61
62 pub fn time_function_with_parent<F, R>(name: &str, parent: &str, f: F) -> R
64 where
65 F: FnOnce() -> R,
66 {
67 let timer = Self::start_with_parent(name, parent);
68 let result = f();
69 timer.stop();
70 result
71 }
72
73 pub fn stop(&self) {
75 if !self.running {
76 return;
77 }
78
79 let elapsed = self.start_time.elapsed();
80 if let Ok(mut profiler) = Profiler::global().lock() {
81 profiler.register_timer_stop(&self.name, elapsed, self.parent.as_deref());
82 }
83 }
84
85 pub fn elapsed(&self) -> Duration {
87 self.start_time.elapsed()
88 }
89
90 pub fn without_auto_report(mut self) -> Self {
92 self.auto_report = false;
93 self
94 }
95
96 pub fn name(&self) -> &str {
98 &self.name
99 }
100
101 pub fn start_time(&self) -> Instant {
103 self.start_time
104 }
105
106 pub fn parent(&self) -> Option<&str> {
108 self.parent.as_deref()
109 }
110
111 pub fn is_running(&self) -> bool {
113 self.running
114 }
115}
116
117impl Drop for Timer {
118 fn drop(&mut self) {
119 if self.running && self.auto_report {
120 let elapsed = self.start_time.elapsed();
121 if let Ok(mut profiler) = Profiler::global().lock() {
122 profiler.register_timer_stop(&self.name, elapsed, self.parent.as_deref());
123 }
124 }
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use std::thread;
132 use std::time::Duration;
133
134 #[test]
135 fn test_timer_basic() {
136 let timer = Timer::start("test_operation");
137 thread::sleep(Duration::from_millis(10));
138 timer.stop();
139
140 let elapsed = timer.elapsed();
141 assert!(elapsed >= Duration::from_millis(10));
142 }
143}