BitMagic-C++: bmtimer.h Source File

BitMagic-C++

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