1
use std::cell::RefCell;
2
use std::rc::Rc;
3
use std::time::Instant;
4

            
5
use log::debug;
6

            
7
#[derive(Default)]
8
pub struct Timing {
9
    results: Rc<RefCell<Vec<(String, f32)>>>,
10
}
11

            
12
pub struct Timer {
13
    name: String,
14
    start: Instant,
15
    results: Rc<RefCell<Vec<(String, f32)>>>,
16
    registered: bool,
17
}
18

            
19
impl Timer {
20
996
    pub fn finish(&mut self) {
21
996
        let time = self.start.elapsed().as_secs_f64();
22
996
        debug!("Time {}: {:.3}s", self.name, time);
23

            
24
        // Register the result.
25
996
        self.results.borrow_mut().push((self.name.clone(), time as f32));
26
996
        self.registered = true
27
996
    }
28
}
29

            
30
impl Drop for Timer {
31
996
    fn drop(&mut self) {
32
996
        if !self.registered {
33
            debug!("Timer {} was dropped before 'finish()'", self.name);
34
996
        }
35
996
    }
36
}
37

            
38
impl Timing {
39
    /// Creates a new timing object to track timers.
40
252
    pub fn new() -> Self {
41
252
        Self {
42
252
            results: Rc::new(RefCell::new(Vec::new())),
43
252
        }
44
252
    }
45

            
46
    /// Starts a new timer with the given name.
47
996
    pub fn start(&mut self, name: &str) -> Timer {
48
996
        Timer {
49
996
            name: name.to_string(),
50
996
            start: Instant::now(),
51
996
            results: self.results.clone(),
52
996
            registered: false,
53
996
        }
54
996
    }
55

            
56
    /// Prints all the finished timers.
57
    pub fn print(&self) {
58
        for (name, time) in self.results.borrow().iter() {
59
            eprintln!("Time {}: {:.3}s", name, time);
60
        }
61
    }
62
}