benchmark_rs/
stopwatch.rs1use std::fmt::{Display, Formatter};
2use std::ops::AddAssign;
3use std::time::{Duration, Instant};
4
5use chrono::{DateTime, Utc};
6
7pub struct StopWatch {
9 accumulated: Duration,
10 checkpoint: Instant,
11 is_stopped: bool,
12}
13
14impl StopWatch {
15 pub fn new() -> StopWatch {
17 StopWatch {
18 accumulated: Duration::from_secs(0),
19 checkpoint: Instant::now(),
20 is_stopped: true,
21 }
22 }
23
24 pub fn start(&mut self) {
26 if self.is_stopped {
27 self.checkpoint = Instant::now();
28 self.is_stopped = false;
29 }
30 }
31
32 pub fn resume(&mut self) {
34 self.start()
35 }
36
37 pub fn reset(&mut self) {
39 self.accumulated = Duration::from_secs(0);
40 self.checkpoint = Instant::now();
41 self.is_stopped = true
42 }
43
44 pub fn stop(&mut self) {
46 if !self.is_stopped {
47 self.accumulated.add_assign(Duration::from_nanos(
48 self.checkpoint.elapsed().as_nanos() as u64
49 ));
50 self.is_stopped = true;
51 }
52 }
53
54 pub fn pause(&mut self) {
56 self.stop()
57 }
58
59 pub fn accumulated(&self) -> Duration {
61 self.accumulated
62 }
63}
64
65impl Display for StopWatch {
66 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
68 let mut accumulated = self.accumulated;
69 if !self.is_stopped {
70 accumulated.add_assign(Duration::from_nanos(
71 self.checkpoint.elapsed().as_nanos() as u64
72 ));
73 }
74 let datetime = DateTime::<Utc>::from_timestamp(
75 accumulated.as_secs() as i64,
76 accumulated.subsec_nanos(),
77 )
78 .unwrap();
79 let formatted_time = datetime.format("%H:%M:%S.%3f").to_string();
80 f.write_fmt(format_args!("{}", formatted_time))
81 }
82}
83
84impl Default for StopWatch {
85 fn default() -> Self {
86 Self::new()
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use std::thread;
93 use std::time::Duration;
94
95 use super::*;
96
97 #[test]
98 fn test_pause() {
99 let mut stop_watch = StopWatch::new();
100 stop_watch.resume();
101 thread::sleep(Duration::from_millis(3));
102 stop_watch.pause();
103 thread::sleep(Duration::from_millis(3));
104 stop_watch.resume();
105 assert!(stop_watch.accumulated() >= Duration::from_millis(3));
106 assert!(stop_watch.accumulated() <= Duration::from_millis(6));
107 }
108
109 #[test]
110 fn test_stopwatch() {
111 let mut stopwatch = StopWatch::new();
112 assert_eq!("00:00:00.000", stopwatch.to_string());
113 stopwatch.start();
114 thread::sleep(Duration::from_millis(3));
115 assert!("00:00:00.003".to_string() <= stopwatch.to_string());
116 thread::sleep(Duration::from_millis(1000));
117 assert!("00:00:01.003".to_string() <= stopwatch.to_string());
118 }
119}