1use std::io::{self, Write};
2use std::time::{Duration, Instant};
3
4/// RAII timer to measure how long phases take.
5#[derive(Debug)]
6pub struct Timer<'a> {
7 output: bool,
8 name: &'a str,
9 start: Instant,
10}
11
12impl<'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
48impl<'a> Drop for Timer<'a> {
49 fn drop(&mut self) {
50 self.print_elapsed();
51 }
52}
53