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 {
48 public:
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 
160 private:
161  std::string m_name; // a string printed in message
162  bool m_running;
163 
164  using CLOCK = std::chrono::high_resolution_clock;
165  using TIME_POINT = std::chrono::time_point<CLOCK>;
166 
168 };
169 
170 
189 template <typename DURATION>
191 {
192 public:
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 
203 private:
206 
208  DURATION& m_duration;
209 };
210 
211 
219 unsigned GetRunningMicroSecs();
220 
221 
226 {
227 public:
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 
264 private:
265  std::string m_name;
266  std::atomic_ullong m_count;
267 };
268 
269 #endif // TPROFILE_H
unsigned long long Count() const
Definition: profile.h:240
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
PROF_TIMER m_counter
< The counter to use to do the profiling
Definition: profile.h:205
SCOPED_PROF_TIMER(DURATION &aDuration)
Definition: profile.h:193
std::chrono::high_resolution_clock CLOCK
Definition: profile.h:164
TIME_POINT m_stoptime
Definition: profile.h:167
A thread-safe event counter.
Definition: profile.h:225
std::string m_name
Definition: profile.h:265
double msecs(bool aSinceLast=false)
Definition: profile.h:147
PROF_COUNTER()
Definition: profile.h:228
bool m_running
Definition: profile.h:162
std::string to_string()
Definition: profile.h:153
unsigned long long operator++(int)
Definition: profile.h:250
A small class to help profiling.
Definition: profile.h:46
DURATION & m_duration
Definition: profile.h:208
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:86
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
Definition: profile.h:103
void Reset()
Definition: profile.h:245
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
DURATION SinceStart(bool aSinceLast=false)
Definition: profile.h:133
PROF_TIMER(const std::string &aName, bool aAutostart=true)
Create a PROF_COUNTER for measuring an elapsed time in milliseconds.
Definition: profile.h:55
void Show(std::ostream &aStream=std::cerr)
Definition: profile.h:255
TIME_POINT m_starttime
Definition: profile.h:167
PROF_COUNTER(const std::string &aName)
Definition: profile.h:234
TIME_POINT m_lasttime
Definition: profile.h:167
std::string m_name
Definition: profile.h:161
void Start()
Start or restart the counter.
Definition: profile.h:75
A simple RAII class to measure the time of an operation.
Definition: profile.h:190
std::atomic_ullong m_count
Definition: profile.h:266