1 | use std::io::{self, Write}; |
2 | use std::time::{Duration, Instant}; |
3 | |
4 | /// RAII timer to measure how long phases take. |
5 | #[derive (Debug)] |
6 | pub struct Timer<'a> { |
7 | output: bool, |
8 | name: &'a str, |
9 | start: Instant, |
10 | } |
11 | |
12 | impl<'a> Timer<'a> { |
13 | /// Creates a Timer with the given name, and starts it. By default, |
14 | /// will print to stderr when it is `drop`'d |
15 | pub fn new(name: &'a str) -> Self { |
16 | Timer { |
17 | output: true, |
18 | name, |
19 | start: Instant::now(), |
20 | } |
21 | } |
22 | |
23 | /// Sets whether or not the Timer will print a message |
24 | /// when it is dropped. |
25 | pub fn with_output(mut self, output: bool) -> Self { |
26 | self.output = output; |
27 | self |
28 | } |
29 | |
30 | /// Returns the time elapsed since the timer's creation |
31 | pub fn elapsed(&self) -> Duration { |
32 | Instant::now() - self.start |
33 | } |
34 | |
35 | fn print_elapsed(&mut self) { |
36 | if self.output { |
37 | let elapsed = self.elapsed(); |
38 | let time = (elapsed.as_secs() as f64) * 1e3 + |
39 | (elapsed.subsec_nanos() as f64) / 1e6; |
40 | let stderr = io::stderr(); |
41 | // Arbitrary output format, subject to change. |
42 | writeln!(stderr.lock(), " time: {:>9.3} ms. \t{}" , time, self.name) |
43 | .expect("timer write should not fail" ); |
44 | } |
45 | } |
46 | } |
47 | |
48 | impl<'a> Drop for Timer<'a> { |
49 | fn drop(&mut self) { |
50 | self.print_elapsed(); |
51 | } |
52 | } |
53 | |