BitMagic-C++
bmtimer.h
Go to the documentation of this file.
1#ifndef BMTIMER__H__INCLUDED__
2#define BMTIMER__H__INCLUDED__
3/*
4Copyright(c) 2002-2021 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17
18For more information please visit: http://bitmagic.io
19*/
20
21/*! \file bmtimer.h
22 \brief Timing utilities for benchmarking (internal)
23*/
24
25#include <iostream>
26#include <iomanip>
27#include <string>
28#include <map>
29#include <chrono>
30
31namespace bm
32{
33
34
35/// Utility class to collect performance measurements and statistics.
36///
37/// @internal
38///
39template<typename TOut=std::ostream>
41{
42public:
43 /// collected statistics
44 ///
46 {
47 std::chrono::duration<double, std::milli> duration;
48 unsigned repeats;
49
51
52 statistics(std::chrono::duration<double, std::milli> d, unsigned r)
53 : duration(d), repeats(r)
54 {}
55 };
56
57 enum format
58 {
61 ct_all
62 };
63
64 /// test name to duration map
65 ///
66 typedef std::map<std::string, statistics > duration_map_type;
67
68public:
69 chrono_taker(TOut& tout,
70 const std::string name,
71 unsigned repeats = 1,
72 duration_map_type* dmap = 0)
73 : tout_(tout),
74 name_(name),
75 repeats_(repeats),
76 dmap_(dmap),
77 is_stopped_(false)
78 {
79 start_ = std::chrono::steady_clock::now();
80 }
81
83 {
84 try
85 {
86 if (!is_stopped_)
87 {
88 stop();
89 }
90 }
91 catch(...)
92 {}
93 }
94
95
96 void stop(bool silent=false)
97 {
98 finish_ = std::chrono::steady_clock::now();
99 auto diff = finish_ - start_;
100 if (dmap_)
101 {
102 statistics st(diff, repeats_);
103 typename duration_map_type::iterator it = dmap_->find(name_);
104 if (it == dmap_->end())
105 {
106 (*dmap_)[name_] = st;
107 }
108 else
109 {
110 it->second.repeats++;
111 it->second.duration += st.duration;
112 }
113 }
114 else // report the measurements
115 {
116 if (!silent)
117 {
118 auto ms = std::chrono::duration <double, std::milli> (diff).count();
120 }
121 }
122 is_stopped_ = true;
123 }
124
125 void add_repeats(unsigned inc)
126 {
127 repeats_ += inc;
128 }
129
130 template<typename DT>
131 static void print_duration(TOut& tout, const std::string& name, DT ms)
132 {
133 if (ms > 1000)
134 {
135 double sec = ms / 1000;
136 if (sec > 60)
137 {
138 double min = sec / 60;
139 tout << name << "; " << std::setprecision(4) << min << " min" << std::endl;
140 }
141 else
142 tout << name << "; " << std::setprecision(4) << sec << " sec" << std::endl;
143 }
144 else
145 tout << name << "; " << ms << " ms" << std::endl;
146 }
147
148
149 static
150 void print_duration_map(TOut& tout, const duration_map_type& dmap, format fmt = ct_time)
151 {
152 typename duration_map_type::const_iterator it = dmap.begin();
153 typename duration_map_type::const_iterator it_end = dmap.end();
154
155 for ( ;it != it_end; ++it)
156 {
157 const chrono_taker::statistics& st = it->second;
158 format f;
159 if (st.repeats <= 1)
160 f = ct_time;
161 else
162 f = fmt;
163
164 switch (f)
165 {
166 case ct_time:
167 print_time:
168 {
169 auto ms = it->second.duration.count();
170 print_duration(tout, it->first, ms);
171 }
172 break;
173 case ct_ops_per_sec:
174 {
175 unsigned iops = (unsigned)((double)st.repeats / (double)it->second.duration.count()) * 1000;
176 if (iops)
177 {
178 tout << it->first << "; " << iops << " ops/sec" << std::endl;
179 }
180 else
181 {
182 double ops = ((double)st.repeats / (double)it->second.duration.count()) * 1000;
183 tout << it->first << "; " << std::setprecision(4) << ops << " ops/sec" << std::endl;
184 }
185 }
186 break;
187 case ct_all:
188 {
189 if (st.repeats <= 1)
190 {
191 goto print_time;
192 }
193 unsigned iops = (unsigned)((double)st.repeats / (double)it->second.duration.count()) * 1000;
194 if (iops)
195 {
196 tout << it->first << "; " << iops << " ops/sec; "
197 << std::setprecision(4) << it->second.duration.count() << " ms" << std::endl;
198 }
199 else
200 {
201 double sec = double(it->second.duration.count()) / 1000;
202 double ops = ((double)st.repeats / (double)it->second.duration.count()) * 1000;
203 tout << it->first << "; " << std::setprecision(4) << ops << " ops/sec; "
204 << std::setprecision(4) << sec << " sec." << std::endl;
205 }
206 }
207 break;
208
209 default:
210 break;
211 }
212 } // for
213 }
214
215
216 chrono_taker(const chrono_taker&) = delete;
218
219protected:
220 TOut& tout_;
221 std::string name_;
222 std::chrono::time_point<std::chrono::steady_clock> start_;
223 std::chrono::time_point<std::chrono::steady_clock> finish_;
224 unsigned repeats_;
227};
228
229
230} // namespace
231
232#endif
Utility class to collect performance measurements and statistics.
Definition: bmtimer.h:41
duration_map_type * dmap_
Definition: bmtimer.h:225
chrono_taker(const chrono_taker &)=delete
void stop(bool silent=false)
Definition: bmtimer.h:96
unsigned repeats_
Definition: bmtimer.h:224
chrono_taker(TOut &tout, const std::string name, unsigned repeats=1, duration_map_type *dmap=0)
Definition: bmtimer.h:69
TOut & tout_
Definition: bmtimer.h:220
std::chrono::time_point< std::chrono::steady_clock > finish_
Definition: bmtimer.h:223
std::map< std::string, statistics > duration_map_type
test name to duration map
Definition: bmtimer.h:66
chrono_taker & operator=(const chrono_taker)=delete
void add_repeats(unsigned inc)
Definition: bmtimer.h:125
static void print_duration_map(TOut &tout, const duration_map_type &dmap, format fmt=ct_time)
Definition: bmtimer.h:150
bool is_stopped_
Definition: bmtimer.h:226
std::chrono::time_point< std::chrono::steady_clock > start_
Definition: bmtimer.h:222
std::string name_
Definition: bmtimer.h:221
static void print_duration(TOut &tout, const std::string &name, DT ms)
Definition: bmtimer.h:131
Definition: bm.h:78
collected statistics
Definition: bmtimer.h:46
std::chrono::duration< double, std::milli > duration
Definition: bmtimer.h:47
statistics(std::chrono::duration< double, std::milli > d, unsigned r)
Definition: bmtimer.h:52