KiCad PCB EDA Suite
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 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 <string>
37#include <iostream>
38#include <iomanip>
39
47{
48public:
55 PROF_TIMER( const std::string& aName, bool aAutostart = true ) :
56 m_name( aName ), m_running( false )
57 {
58 if( aAutostart )
59 Start();
60 }
61
68 {
69 Start();
70 }
71
75 void Start()
76 {
77 m_running = true;
78 m_starttime = CLOCK::now();
80 }
81
82
86 void Stop()
87 {
88 if( !m_running )
89 return;
90
91 m_stoptime = CLOCK::now();
92 m_running = false;
93 }
94
103 void Show( std::ostream& aStream = std::cerr )
104 {
105 using DURATION = std::chrono::duration<double, std::nano>;
106
107 const auto duration = SinceStart<DURATION>();
108 const double cnt = duration.count();
109
110 if( m_name.size() )
111 {
112 aStream << m_name << " took ";
113 }
114
115 if( cnt < 1e3 )
116 aStream << cnt << "ns";
117 else if( cnt < 1e6 )
118 aStream << cnt / 1e3 << "┬Ás";
119 else if( cnt < 1e9 )
120 aStream << cnt / 1e6 << "ms";
121 else
122 aStream << cnt / 1e9 << "s";
123
124 aStream << std::endl;
125 }
126
132 template <typename DURATION>
133 DURATION SinceStart( bool aSinceLast = false )
134 {
135 const TIME_POINT stoptime = m_running ? CLOCK::now() : m_stoptime;
136 const TIME_POINT starttime = aSinceLast ? m_lasttime : m_starttime;
137
138 m_lasttime = stoptime;
139
140 return std::chrono::duration_cast<DURATION>( stoptime - starttime );
141 }
142
147 double msecs( bool aSinceLast = false )
148 {
149 using DUR_MS = std::chrono::duration<double, std::milli>;
150 return SinceStart<DUR_MS>( aSinceLast ).count();
151 }
152
153 std::string to_string()
154 {
155 char tmp[1024];
156 snprintf( tmp, sizeof( tmp ), "%s: %-6.1fms", m_name.c_str(), msecs() );
157 return tmp;
158 }
159
160private:
161 std::string m_name; // a string printed in message
163
164 using CLOCK = std::chrono::high_resolution_clock;
165 using TIME_POINT = std::chrono::time_point<CLOCK>;
166
168};
169
170
189template <typename DURATION>
191{
192public:
193 SCOPED_PROF_TIMER( DURATION& aDuration ) : PROF_TIMER(), m_duration( aDuration )
194 {
195 }
196
198 {
199 // update the output
200 m_duration = m_counter.SinceStart<DURATION>();
201 }
202
203private:
206
208 DURATION& m_duration;
209};
210
211
220
221
226{
227public:
229 m_name( "Anonymous" ),
230 m_count( 0 )
231 {
232 }
233
234 PROF_COUNTER( const std::string& aName ) :
235 m_name( aName ),
236 m_count( 0 )
237 {
238 }
239
240 unsigned long long Count() const
241 {
242 return m_count.load();
243 }
244
245 void Reset()
246 {
247 m_count.store( 0 );
248 }
249
250 unsigned long long operator++( int )
251 {
252 return m_count++;
253 }
254
255 void Show( std::ostream& aStream = std::cerr )
256 {
257 if( m_name.size() )
258 aStream << m_name << ": ";
259
260 aStream << m_count.load();
261 aStream << std::endl;
262 }
263
264private:
265 std::string m_name;
266 std::atomic_ullong m_count;
267};
268
269#endif // TPROFILE_H
A thread-safe event counter.
Definition: profile.h:226
unsigned long long operator++(int)
Definition: profile.h:250
PROF_COUNTER(const std::string &aName)
Definition: profile.h:234
unsigned long long Count() const
Definition: profile.h:240
void Show(std::ostream &aStream=std::cerr)
Definition: profile.h:255
std::atomic_ullong m_count
Definition: profile.h:266
void Reset()
Definition: profile.h:245
PROF_COUNTER()
Definition: profile.h:228
std::string m_name
Definition: profile.h:265
A small class to help profiling.
Definition: profile.h:47
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:103
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:86
std::chrono::high_resolution_clock CLOCK
Definition: profile.h:164
DURATION SinceStart(bool aSinceLast=false)
Definition: profile.h:133
void Start()
Start or restart the counter.
Definition: profile.h:75
TIME_POINT m_lasttime
Definition: profile.h:167
std::string to_string()
Definition: profile.h:153
TIME_POINT m_stoptime
Definition: profile.h:167
bool m_running
Definition: profile.h:162
PROF_TIMER()
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition: profile.h:67
std::chrono::time_point< CLOCK > TIME_POINT
Definition: profile.h:165
TIME_POINT m_starttime
Definition: profile.h:167
PROF_TIMER(const std::string &aName, bool aAutostart=true)
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition: profile.h:55
std::string m_name
Definition: profile.h:161
double msecs(bool aSinceLast=false)
Definition: profile.h:147
A simple RAII class to measure the time of an operation.
Definition: profile.h:191
DURATION & m_duration
Definition: profile.h:208
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition: profile.h:193
PROF_TIMER m_counter
< The counter to use to do the profiling
Definition: profile.h:205
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.