GCC Code Coverage Report


Directory: ./
File: src/utils/stop-watch.cpp
Date: 2025-05-13 12:28:21
Exec Total Coverage
Lines: 37 132 28.0%
Branches: 19 208 9.1%

Line Branch Exec Source
1 /*
2 Copyright (c) 2010-2013 Tommaso Urli
3
4 Tommaso Urli tommaso.urli@uniud.it University of Udine
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 */
26
27 #ifndef WIN32
28 #include <sys/time.h>
29 #else
30 #include <Windows.h>
31
32 #include <iomanip>
33 #endif
34
35 #include <iomanip> // std::setprecision
36
37 #include "sot/core/stop-watch.hh"
38
39 using std::map;
40 using std::ostringstream;
41 using std::string;
42
43 //#define START_PROFILER(name) getProfiler().start(name)
44 //#define STOP_PROFILER(name) getProfiler().stop(name)
45
46 8 Stopwatch &getProfiler() {
47
4/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
8 static Stopwatch s(REAL_TIME); // alternatives are CPU_TIME and REAL_TIME
48 8 return s;
49 }
50
51 2 Stopwatch::Stopwatch(StopwatchMode _mode) : active(true), mode(_mode) {
52 2 records_of = new map<string, PerformanceData>();
53 2 }
54
55
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 Stopwatch::~Stopwatch() { delete records_of; }
56
57 ✗ void Stopwatch::set_mode(StopwatchMode new_mode) { mode = new_mode; }
58
59 4 bool Stopwatch::performance_exists(string perf_name) {
60
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 return (records_of->find(perf_name) != records_of->end());
61 }
62
63 8 long double Stopwatch::take_time() {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (mode == CPU_TIME) {
65 // Use ctime
66 ✗ return clock();
67
68
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 } else if (mode == REAL_TIME) {
69 // Query operating system
70
71 #ifdef WIN32
72 /* In case of usage under Windows */
73 FILETIME ft;
74 LARGE_INTEGER intervals;
75
76 // Get the amount of 100 nanoseconds intervals elapsed since January 1, 1601
77 // (UTC)
78 GetSystemTimeAsFileTime(&ft);
79 intervals.LowPart = ft.dwLowDateTime;
80 intervals.HighPart = ft.dwHighDateTime;
81
82 long double measure = intervals.QuadPart;
83 measure -= 116444736000000000.0; // Convert to UNIX epoch time
84 measure /= 10000000.0; // Convert to seconds
85
86 return measure;
87 #else
88 /* Linux, MacOS, ... */
89 struct timeval tv;
90 8 gettimeofday(&tv, NULL);
91
92 8 long double measure = tv.tv_usec;
93 8 measure /= 1000000.0; // Convert to seconds
94 8 measure += tv.tv_sec; // Add seconds part
95
96 8 return measure;
97 #endif
98
99 } else {
100 // If mode == NONE, clock has not been initialized, then throw exception
101 ✗ throw StopwatchException("Clock not initialized to a time taking mode!");
102 }
103 }
104
105 4 void Stopwatch::start(string perf_name) {
106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!active) return;
107
108 // Just works if not already present
109
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 records_of->insert(make_pair(perf_name, PerformanceData()));
110
111 4 PerformanceData &perf_info = records_of->find(perf_name)->second;
112
113 // Take ctime
114 4 perf_info.clock_start = take_time();
115
116 // If this is a new start (i.e. not a restart)
117 // if (!perf_info.paused)
118 // perf_info.last_time = 0;
119
120 4 perf_info.paused = false;
121 }
122
123 4 void Stopwatch::stop(string perf_name) {
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!active) return;
125
126 4 long double clock_end = take_time();
127
128 // Try to recover performance data
129
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
4 if (!performance_exists(perf_name))
130 ✗ throw StopwatchException("Performance not initialized.");
131
132 4 PerformanceData &perf_info = records_of->find(perf_name)->second;
133
134 // check whether the performance has been reset
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (perf_info.clock_start == 0) return;
136
137 4 perf_info.stops++;
138 4 long double lapse = clock_end - perf_info.clock_start;
139
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
141
142 // Update last time
143 4 perf_info.last_time = lapse;
144
145 // Update min/max time
146
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (lapse >= perf_info.max_time) perf_info.max_time = lapse;
147
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if (lapse <= perf_info.min_time || perf_info.min_time == 0)
148 4 perf_info.min_time = lapse;
149
150 // Update total time
151 4 perf_info.total_time += lapse;
152 }
153
154 ✗ void Stopwatch::pause(string perf_name) {
155 ✗ if (!active) return;
156
157 ✗ long double clock_end = clock();
158
159 // Try to recover performance data
160 ✗ if (!performance_exists(perf_name))
161 ✗ throw StopwatchException("Performance not initialized.");
162
163 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
164
165 // check whether the performance has been reset
166 ✗ if (perf_info.clock_start == 0) return;
167
168 ✗ long double lapse = clock_end - perf_info.clock_start;
169
170 // Update total time
171 ✗ perf_info.last_time += lapse;
172 ✗ perf_info.total_time += lapse;
173 }
174
175 ✗ void Stopwatch::reset_all() {
176 ✗ if (!active) return;
177
178 ✗ map<string, PerformanceData>::iterator it;
179
180 ✗ for (it = records_of->begin(); it != records_of->end(); ++it) {
181 ✗ reset(it->first);
182 }
183 }
184
185 ✗ void Stopwatch::report_all(int precision, std::ostream &output) {
186 ✗ if (!active) return;
187
188 output << "\n*** PROFILING RESULTS [ms] (min - avg - max - lastTime - "
189 ✗ "nSamples - totalTime) ***\n";
190 ✗ map<string, PerformanceData>::iterator it;
191 ✗ for (it = records_of->begin(); it != records_of->end(); ++it) {
192 ✗ report(it->first, precision, output);
193 }
194 }
195
196 ✗ void Stopwatch::reset(string perf_name) {
197 ✗ if (!active) return;
198
199 // Try to recover performance data
200 ✗ if (!performance_exists(perf_name))
201 ✗ throw StopwatchException("Performance not initialized.");
202
203 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
204
205 ✗ perf_info.clock_start = 0;
206 ✗ perf_info.total_time = 0;
207 ✗ perf_info.min_time = 0;
208 ✗ perf_info.max_time = 0;
209 ✗ perf_info.last_time = 0;
210 ✗ perf_info.paused = false;
211 ✗ perf_info.stops = 0;
212 }
213
214 ✗ void Stopwatch::turn_on() {
215 ✗ std::cout << "Stopwatch active." << std::endl;
216 ✗ active = true;
217 }
218
219 ✗ void Stopwatch::turn_off() {
220 ✗ std::cout << "Stopwatch inactive." << std::endl;
221 ✗ active = false;
222 }
223
224 ✗ void Stopwatch::report(string perf_name, int precision, std::ostream &output) {
225 ✗ if (!active) return;
226
227 // Try to recover performance data
228 ✗ if (!performance_exists(perf_name))
229 ✗ throw StopwatchException("Performance not initialized.");
230
231 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
232
233 ✗ string pad = "";
234 ✗ for (size_t i = perf_name.length(); i < STOP_WATCH_MAX_NAME_LENGTH; i++)
235 ✗ pad.append(" ");
236
237 ✗ output << perf_name << pad;
238 ✗ output << std::fixed << std::setprecision(precision)
239 ✗ << (perf_info.min_time * 1e3) << "\t";
240 ✗ output << std::fixed << std::setprecision(precision)
241 ✗ << (perf_info.total_time * 1e3 / (long double)perf_info.stops) << "\t";
242 ✗ output << std::fixed << std::setprecision(precision)
243 ✗ << (perf_info.max_time * 1e3) << "\t";
244 ✗ output << std::fixed << std::setprecision(precision)
245 ✗ << (perf_info.last_time * 1e3) << "\t";
246 ✗ output << std::fixed << std::setprecision(precision) << perf_info.stops
247 ✗ << std::endl;
248 ✗ output << std::fixed << std::setprecision(precision)
249 ✗ << perf_info.total_time * 1e3 << std::endl;
250 }
251
252 ✗ long double Stopwatch::get_time_so_far(string perf_name) {
253 // Try to recover performance data
254 ✗ if (!performance_exists(perf_name))
255 ✗ throw StopwatchException("Performance not initialized.");
256
257 long double lapse =
258 ✗ (take_time() - (records_of->find(perf_name)->second).clock_start);
259
260 ✗ if (mode == CPU_TIME) lapse /= (double)CLOCKS_PER_SEC;
261
262 ✗ return lapse;
263 }
264
265 ✗ long double Stopwatch::get_total_time(string perf_name) {
266 // Try to recover performance data
267 ✗ if (!performance_exists(perf_name))
268 ✗ throw StopwatchException("Performance not initialized.");
269
270 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
271
272 ✗ return perf_info.total_time;
273 }
274
275 ✗ long double Stopwatch::get_average_time(string perf_name) {
276 // Try to recover performance data
277 ✗ if (!performance_exists(perf_name))
278 ✗ throw StopwatchException("Performance not initialized.");
279
280 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
281
282 ✗ return (perf_info.total_time / (long double)perf_info.stops);
283 }
284
285 ✗ long double Stopwatch::get_min_time(string perf_name) {
286 // Try to recover performance data
287 ✗ if (!performance_exists(perf_name))
288 ✗ throw StopwatchException("Performance not initialized.");
289
290 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
291
292 ✗ return perf_info.min_time;
293 }
294
295 ✗ long double Stopwatch::get_max_time(string perf_name) {
296 // Try to recover performance data
297 ✗ if (!performance_exists(perf_name))
298 ✗ throw StopwatchException("Performance not initialized.");
299
300 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
301
302 ✗ return perf_info.max_time;
303 }
304
305 ✗ long double Stopwatch::get_last_time(string perf_name) {
306 // Try to recover performance data
307 ✗ if (!performance_exists(perf_name))
308 ✗ throw StopwatchException("Performance not initialized.");
309
310 ✗ PerformanceData &perf_info = records_of->find(perf_name)->second;
311
312 ✗ return perf_info.last_time;
313 }
314