KiCad PCB EDA Suite
Loading...
Searching...
No Matches
profile.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2013 CERN
5 * Copyright (C) 2019-2020, 2024 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
31#ifndef TPROFILE_H
32#define TPROFILE_H
33
34#include <atomic>
35#include <chrono>
36#include <sstream>
37#include <string>
38#include <iostream>
39#include <iomanip>
40#include <cstdint>
41
49{
50public:
57 PROF_TIMER( const std::string& aName, bool aAutostart = true ) :
58 m_name( aName ), m_running( false )
59 {
60 if( aAutostart )
61 Start();
62 }
63
70 {
71 Start();
72 }
73
77 void Start()
78 {
79 m_running = true;
80 m_starttime = CLOCK::now();
82 }
83
84
88 void Stop()
89 {
90 if( !m_running )
91 return;
92
93 m_stoptime = CLOCK::now();
94 m_running = false;
95 }
96
105 void Show( std::ostream& aStream = std::cerr )
106 {
107 using DURATION = std::chrono::duration<double, std::nano>;
108
109 const auto duration = SinceStart<DURATION>();
110 const double cnt = duration.count();
111
112 if( m_name.size() )
113 {
114 aStream << m_name << " took ";
115 }
116
117 if( cnt < 1e3 )
118 aStream << cnt << "ns";
119 else if( cnt < 1e6 )
120 aStream << ( cnt / 1e3 ) << "µs";
121 else if( cnt < 1e9 )
122 aStream << ( cnt / 1e6 ) << "ms";
123 else
124 aStream << ( cnt / 1e9 ) << "s";
125
126 aStream << std::endl;
127 }
128
134 template <typename DURATION>
135 DURATION SinceStart( bool aSinceLast = false )
136 {
137 const TIME_POINT stoptime = m_running ? CLOCK::now() : m_stoptime;
138 const TIME_POINT starttime = aSinceLast ? m_lasttime : m_starttime;
139
140 m_lasttime = stoptime;
141
142 return std::chrono::duration_cast<DURATION>( stoptime - starttime );
143 }
144
149 double msecs( bool aSinceLast = false )
150 {
151 using DUR_MS = std::chrono::duration<double, std::milli>;
152 return SinceStart<DUR_MS>( aSinceLast ).count();
153 }
154
155 std::string to_string()
156 {
157 using DURATION = std::chrono::duration<double, std::nano>;
158
159 const auto duration = SinceStart<DURATION>();
160 const double cnt = duration.count();
161 std::string retv;
162
163 if( !m_name.empty() )
164 retv = m_name + ": ";
165
166 std::stringstream time;
167
168 if( cnt < 1e3 )
169 time << cnt << "ns";
170 else if( cnt < 1e6 )
171 time << ( cnt / 1e3 ) << "µs";
172 else if( cnt < 1e9 )
173 time << ( cnt / 1e6 ) << "ms";
174 else
175 time << ( cnt / 1e9 ) << "s";
176
177 retv += time.str();
178
179 return retv;
180 }
181
182private:
183 std::string m_name; // a string printed in message
185
186 using CLOCK = std::chrono::high_resolution_clock;
187 using TIME_POINT = std::chrono::time_point<CLOCK>;
188
190};
191
192
211template <typename DURATION>
213{
214public:
215 SCOPED_PROF_TIMER( DURATION& aDuration ) : PROF_TIMER(), m_duration( aDuration )
216 {
217 }
218
220 {
221 // update the output
222 m_duration = m_counter.SinceStart<DURATION>();
223 }
224
225private:
228
230 DURATION& m_duration;
231};
232
233
242
243
248{
249public:
251 m_name( "Anonymous" ),
252 m_count( 0 )
253 {
254 }
255
256 PROF_COUNTER( const std::string& aName ) :
257 m_name( aName ),
258 m_count( 0 )
259 {
260 }
261
262 unsigned long long Count() const
263 {
264 return m_count.load();
265 }
266
267 void Reset()
268 {
269 m_count.store( 0 );
270 }
271
272 unsigned long long operator++( int )
273 {
274 return m_count++;
275 }
276
277 void Show( std::ostream& aStream = std::cerr )
278 {
279 if( m_name.size() )
280 aStream << m_name << ": ";
281
282 aStream << m_count.load();
283 aStream << std::endl;
284 }
285
286private:
287 std::string m_name;
288 std::atomic_ullong m_count;
289};
290
291#endif // TPROFILE_H
A thread-safe event counter.
Definition: profile.h:248
unsigned long long operator++(int)
Definition: profile.h:272
PROF_COUNTER(const std::string &aName)
Definition: profile.h:256
unsigned long long Count() const
Definition: profile.h:262
void Show(std::ostream &aStream=std::cerr)
Definition: profile.h:277
std::atomic_ullong m_count
Definition: profile.h:288
void Reset()
Definition: profile.h:267
PROF_COUNTER()
Definition: profile.h:250
std::string m_name
Definition: profile.h:287
A small class to help profiling.
Definition: profile.h:49
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:105
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:88
std::chrono::high_resolution_clock CLOCK
Definition: profile.h:186
DURATION SinceStart(bool aSinceLast=false)
Definition: profile.h:135
void Start()
Start or restart the counter.
Definition: profile.h:77
TIME_POINT m_lasttime
Definition: profile.h:189
std::string to_string()
Definition: profile.h:155
TIME_POINT m_stoptime
Definition: profile.h:189
bool m_running
Definition: profile.h:184
PROF_TIMER()
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition: profile.h:69
std::chrono::time_point< CLOCK > TIME_POINT
Definition: profile.h:187
TIME_POINT m_starttime
Definition: profile.h:189
PROF_TIMER(const std::string &aName, bool aAutostart=true)
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition: profile.h:57
std::string m_name
Definition: profile.h:183
double msecs(bool aSinceLast=false)
Definition: profile.h:149
A simple RAII class to measure the time of an operation.
Definition: profile.h:213
DURATION & m_duration
Definition: profile.h:230
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition: profile.h:215
PROF_TIMER m_counter
< The counter to use to do the profiling
Definition: profile.h:227
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.