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 new(name: &'a str) -> Self15 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. with_output(mut self, output: bool) -> Self25 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 elapsed(&self) -> Duration31 pub fn elapsed(&self) -> Duration { 32 Instant::now() - self.start 33 } 34 print_elapsed(&mut self)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> { drop(&mut self)49 fn drop(&mut self) { 50 self.print_elapsed(); 51 } 52 } 53