mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
Timer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <mutable/util/fn.hpp>
5#include <algorithm>
6#include <chrono>
7#include <ctime>
8#include <string>
9#include <utility>
10#include <vector>
11
12
13namespace m {
14
16struct Timer
17{
20 {
21 friend struct Timer;
22
23 private:
25 std::size_t id_;
26
27 TimingProcess(Timer &timer, std::size_t index) : timer_(timer), id_(index) { }
28
29 public:
31 auto &M = timer_.get(id_);
32 if (not M.has_ended())
34 }
35
36 void stop() { timer_.stop(id_); }
37 };
38
39 using clock = std::chrono::high_resolution_clock;
40 using duration = clock::duration;
41 using time_point = clock::time_point;
42
44 {
45 std::string name;
47
49 : name(std::move(name))
50 , begin(std::move(begin))
51 , end(std::move(end))
52 { }
53
55 void clear() { begin = end = time_point(); }
56
58 void start() {
60 begin = clock::now();
61 }
62
64 void stop() {
66 end = clock::now();
67 }
68
70 bool is_unused() const {
72 "if the measurement hasn't started it must not have ended");
73 return not has_started();
74 }
76 bool has_started() const { return begin != time_point(); }
78 bool has_ended() const { return end != time_point(); }
80 bool is_active() const { return has_started() and not has_ended(); }
82 bool is_finished() const { return has_started() and has_ended(); }
83
86 M_insist(is_finished(), "can only compute duration of finished measurements");
87 return end - begin;
88 }
89
90 friend std::ostream & operator<<(std::ostream &out, const Measurement &M);
91 void dump(std::ostream &out) const;
92 void dump() const;
93 };
94
95 private:
96 std::vector<Measurement> measurements_;
97
98 public:
99 auto begin() const { return measurements_.cbegin(); }
100 auto end() const { return measurements_.cend(); }
101 auto cbegin() const { return measurements_.cbegin(); }
102 auto cend() const { return measurements_.cend(); }
103
104 const std::vector<Measurement> & measurements() const { return measurements_; }
105 const Measurement & get(std::size_t i) const {
106 if (i >= measurements_.size())
107 throw m::out_of_range("index i out of bounds");
108 return measurements_[i];
109 }
110 const Measurement & get(const std::string &name) const {
111 auto it = std::find_if(measurements_.begin(), measurements_.end(),
112 [&](auto &elem) { return elem.name == name; });
113 if (it == measurements_.end())
114 throw m::out_of_range("a measurement with that name does not exist");
115 return *it;
116 }
117
119 void clear() { measurements_.clear(); }
120
121 private:
123 std::size_t start(std::string name) {
124 auto it = std::find_if(measurements_.begin(), measurements_.end(),
125 [&](auto &elem) { return elem.name == name; });
126
127 if (it != measurements_.end()) { // overwrite existing, finished measurement
128 if (it->is_active())
129 throw m::invalid_argument("a measurement with that name is already in progress");
130 const auto idx = std::distance(measurements_.begin(), it);
131 it->end = time_point();
132 it->begin = clock::now();
133 return idx;
134 } else { // create new measurement
135 auto id = measurements_.size();
136 auto &M = measurements_.emplace_back(name);
137 M.start();
138 return id;
139 }
140 }
141
143 void stop(std::size_t id) {
144 M_insist(id < measurements_.size(), "id out of bounds");
145 auto &M = measurements_[id];
146 M_insist(not M.has_ended(), "cannot stop that measurement because it has already been stopped");
147 M.stop();
148 }
149
150 public:
152 TimingProcess create_timing(std::string name) { return TimingProcess(*this, /* ID= */ start(name)); }
153
156 friend std::ostream & operator<<(std::ostream &out, const Timer &timer) {
157 out << "Timer measurements:\n";
158 for (auto &M : timer)
159 out << " " << M << '\n';
160
161 return out;
162 }
163
164 void dump(std::ostream &out) const;
165 void dump() const;
167
169 duration total() const {
170 duration d(0);
171 for (auto &m : measurements_)
172 d += m.duration();
173 return d;
174 }
175};
176
177#define M_TIME_EXPR(EXPR, DESCR, TIMER) \
178 [&]() { auto TP = (TIMER).create_timing((DESCR)); return (EXPR); }();
179#define M_TIME_BLOCK(DESCR, TIMER, BLOCK) {\
180 auto TP = (TIMER).create_timing((DESCR)); \
181 BLOCK \
182}
183#define M_TIME_THIS(DESCR, TIMER) \
184 auto M_PASTE(__timer_, __COUNTER__) = (TIMER).create_timing((DESCR));
185
186}
#define id(X)
#define M_insist(...)
Definition: macro.hpp:129
‍mutable namespace
Definition: Backend.hpp:10
and
Definition: enum_ops.hpp:12
STL namespace.
time_point begin
Definition: Timer.hpp:46
duration duration() const
Returns the duration of a finished Measurement.
Definition: Timer.hpp:85
bool has_ended() const
Returns true iff this Measurement has ended.
Definition: Timer.hpp:78
bool is_finished() const
Returns true iff this Measurement has completed.
Definition: Timer.hpp:82
void stop()
Stop this Measurement by setting the end time point to NOW.
Definition: Timer.hpp:64
void dump() const
Definition: Timer.cpp:24
void start()
Start this Measurement by setting the start time point to NOW.
Definition: Timer.hpp:58
bool is_unused() const
Returns true iff the Measurement is unused, i.e.
Definition: Timer.hpp:70
bool is_active() const
Returns true iff this Measurement is currently in process.
Definition: Timer.hpp:80
void clear()
Clear this Measurement, rendering it unused.
Definition: Timer.hpp:55
std::string name
the name of this Measurement
Definition: Timer.hpp:45
friend std::ostream & operator<<(std::ostream &out, const Measurement &M)
Measurement(std::string name, time_point begin=time_point(), time_point end=time_point())
Definition: Timer.hpp:48
bool has_started() const
Returns true iff this Measurement has begun.
Definition: Timer.hpp:76
time_point end
the begin and end time points of this Measurement
Definition: Timer.hpp:46
A proxy class to record a Measurement with a Timer.
Definition: Timer.hpp:20
std::size_t id_
the ID of the Measurement
Definition: Timer.hpp:25
Timer & timer_
the Timer instance
Definition: Timer.hpp:24
TimingProcess(Timer &timer, std::size_t index)
Definition: Timer.hpp:27
Collect timings of events.
Definition: Timer.hpp:17
void clear()
Erase all Measurements from this Timer.
Definition: Timer.hpp:119
auto cend() const
Definition: Timer.hpp:102
M_LCOV_EXCL_STOP duration total() const
Computes the total duration of all Measurements.
Definition: Timer.hpp:169
const std::vector< Measurement > & measurements() const
Definition: Timer.hpp:104
auto end() const
Definition: Timer.hpp:100
void dump() const
Definition: Timer.cpp:27
std::chrono::high_resolution_clock clock
Definition: Timer.hpp:39
auto begin() const
Definition: Timer.hpp:99
const Measurement & get(const std::string &name) const
Definition: Timer.hpp:110
const Measurement & get(std::size_t i) const
Definition: Timer.hpp:105
TimingProcess create_timing(std::string name)
Creates a new TimingProcess with the given name.
Definition: Timer.hpp:152
clock::time_point time_point
Definition: Timer.hpp:41
clock::duration duration
Definition: Timer.hpp:40
M_LCOV_EXCL_START friend std::ostream & operator<<(std::ostream &out, const Timer &timer)
Print all finished and in-process timings of timer to out.
Definition: Timer.hpp:156
std::vector< Measurement > measurements_
Definition: Timer.hpp:96
auto cbegin() const
Definition: Timer.hpp:101
std::size_t start(std::string name)
Start a new Measurement with the name name.
Definition: Timer.hpp:123
void stop(std::size_t id)
Stops the Measurement with the given ID.
Definition: Timer.hpp:143
Signals that an argument to a function of method was invalid.
Definition: exception.hpp:37
Signals that an index-based or key-based access was out of range.
Definition: exception.hpp:43