gbench/
bench.rs

1use std::mem;
2use std::time::Instant;
3
4use crate::global::{begin, begin_time, end, gen_id, get_id, queue_mutex, BenchData};
5use crate::writer::Writer;
6
7fn ts_of(instant: Instant) -> f32 {
8    (instant.duration_since(begin_time()).as_nanos() as f32) / 1000.0
9}
10
11fn enqueue(data: BenchData) {
12    let mut lock = queue_mutex();
13    lock.push(data);
14}
15
16pub fn _log(log: String) {
17    let ts = ts_of(Instant::now());
18    let tid = get_id();
19
20    enqueue(BenchData::Log { log, ts, tid });
21}
22
23fn bench(name: String, ts: f32) {
24    let dur = ts_of(Instant::now()) - ts;
25    let tid = get_id();
26
27    enqueue(BenchData::Bench { name, ts, dur, tid });
28}
29
30pub fn _count(name: String, data: Vec<(String, f32)>) {
31    let ts = ts_of(Instant::now());
32    let tid = get_id();
33
34    enqueue(BenchData::Count {
35        name,
36        data,
37        ts,
38        tid,
39    });
40}
41
42/// Starts a benchmarking scope on creation and ends it on drop
43///
44/// TimeScope saves the Instant it was created. When dropped it
45/// saves the benchmarking results to the file.
46///
47/// Using [scope!] macro instead of this struct is recommened.
48///
49/// [scope!]: macro.scope.html
50pub struct TimeScope {
51    start: f32,
52    name: String,
53}
54
55impl TimeScope {
56    pub fn new(name: String) -> TimeScope {
57        gen_id();
58        TimeScope {
59            start: ts_of(Instant::now()),
60            name,
61        }
62    }
63}
64
65impl Drop for TimeScope {
66    fn drop(&mut self) {
67        bench(mem::replace(&mut self.name, String::new()), self.start);
68    }
69}
70
71/// Instantiates global data on creation and deinstantiates it on drop
72///
73/// This struct instantiates global data upon creation
74/// and deinstantiates it upon drop. It also is responsible
75/// for calling the writers when the data is collected.
76///
77/// Using [instantiate!] macro instead of this struct is recommened.
78///
79/// [instantiate!]: macro.instantiate.html
80pub struct Instantiator {
81    alive: bool,
82    writers: Vec<Box<dyn Writer + 'static>>,
83}
84
85impl Instantiator {
86    /// Constructs the instantiator
87    ///
88    /// The writers will be called in [end] method.
89    ///
90    /// [end]: struct.Instantiator.html#method.end
91    pub fn new(writers: Vec<Box<dyn Writer + 'static>>) -> Instantiator {
92        begin();
93        Instantiator {
94            alive: true,
95            writers,
96        }
97    }
98
99    /// Deinstantiates global variables and calls the writers
100    ///
101    /// This method is used when Instantiator is never dropped.
102    // This method is called on drop.
103    pub fn end(&mut self) {
104        if self.alive {
105            self.alive = false;
106            end(mem::replace(&mut self.writers, Vec::new()));
107        }
108    }
109}
110
111impl Drop for Instantiator {
112    fn drop(&mut self) {
113        self.end();
114    }
115}