| 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 | |