Main MRPT website > C++ reference for MRPT 1.9.9
CTimeLogger.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/utils/CTimeLogger.h>
15 
16 #include <iostream>
17 
18 using namespace mrpt;
19 using namespace mrpt::utils;
20 using namespace mrpt::system;
21 using namespace std;
22 
24 {
25  MyGlobalProfiler() : mrpt::utils::CTimeLogger("MRPT_global_profiler") {}
27  {
28  if (!m_data.empty())
29  {
30  const std::string sFil("mrpt-global-profiler.csv");
31  this->saveToCSVFile(sFil);
32  std::cout << "[MRPT global profiler] Write stats to: " << sFil
33  << std::endl;
34  }
35  }
36 };
38 
39 namespace mrpt
40 {
41 namespace utils
42 {
44 void global_profiler_enter(const char* func_name) noexcept
45 {
46  global_profiler.enter(func_name);
47 }
48 void global_profiler_leave(const char* func_name) noexcept
49 {
50  global_profiler.leave(func_name);
51 }
52 }
53 }
54 
56  bool enabled /*=true*/, const std::string& name /*=""*/)
57  : COutputLogger("CTimeLogger"), m_tictac(), m_enabled(enabled), m_name(name)
58 {
59  m_tictac.Tic();
60 }
61 
63 {
64  // Dump all stats:
65  if (!m_data.empty()) // If logging is disabled, do nothing...
66  dumpAllStats();
67 }
68 
70  : COutputLogger(o),
71  m_enabled(o.m_enabled),
72  m_name(o.m_name),
73  m_data(o.m_data)
74 {
75 }
77 {
78  COutputLogger::operator=(o);
79  m_enabled = o.m_enabled;
80  m_name = o.m_name;
81  m_data = o.m_data;
82  return *this;
83 }
85  : COutputLogger(o),
86  m_enabled(o.m_enabled),
87  m_name(o.m_name),
88  m_data(o.m_data)
89 {
90 }
92 {
93  COutputLogger::operator=(o);
94  m_enabled = o.m_enabled;
95  m_name = o.m_name;
96  m_data = o.m_data;
97  return *this;
98 }
99 
100 void CTimeLogger::clear(bool deep_clear)
101 {
102  if (deep_clear)
103  m_data.clear();
104  else
105  {
106  for (auto& e : m_data) e.second = TCallData();
107  }
108 }
109 
111 {
112  std::string ret;
113 
114  for (size_t p = 0; p < s.size(); p += len)
115  {
116  ret += rightPad(s.c_str() + p, len, true);
117  if (p + len < s.size()) ret += "\n";
118  }
119  return ret;
120 }
121 
122 void CTimeLogger::getStats(std::map<std::string, TCallStats>& out_stats) const
123 {
124  out_stats.clear();
125  for (const auto e : m_data)
126  {
127  TCallStats& cs = out_stats[e.first];
128  cs.min_t = e.second.min_t;
129  cs.max_t = e.second.max_t;
130  cs.total_t = e.second.mean_t;
131  cs.mean_t = e.second.n_calls ? e.second.mean_t / e.second.n_calls : 0;
132  cs.n_calls = e.second.n_calls;
133  cs.last_t = e.second.last_t;
134  }
135 }
136 
137 std::string CTimeLogger::getStatsAsText(const size_t column_width) const
138 {
139  std::string stats_text;
140  std::string name_tmp = m_name.size() ? " " + m_name + ": " : " ";
141  std::string mrpt_string = "MRPT CTimeLogger report ";
142 
143  std::string top_header(name_tmp + mrpt_string);
144  // append dashes to the header to reach column_width
145  {
146  int space_to_fill = top_header.size() < column_width
147  ? (column_width - top_header.size()) / 2
148  : 2;
149  std::string dashes_half(space_to_fill, '-');
150  top_header = dashes_half + top_header + dashes_half;
151  if (dashes_half.size() % 2)
152  { // what if column_width-top_header.size() is odd?
153  top_header += '-';
154  }
155  }
156 
157  std::string middle_header(
158  " FUNCTION #CALLS MIN.T MEAN.T "
159  "MAX.T TOTAL ");
160  std::string bottom_header(column_width, '-');
161 
162  stats_text += top_header + "\n";
163  stats_text += middle_header + "\n";
164  stats_text += bottom_header + "\n";
165 
166  // for all the timed sections
167  for (const auto i : m_data)
168  {
169  const string sMinT = unitsFormat(i.second.min_t, 1, false);
170  const string sMaxT = unitsFormat(i.second.max_t, 1, false);
171  const string sTotalT = unitsFormat(i.second.mean_t, 1, false);
172  const string sMeanT = unitsFormat(
173  i.second.n_calls ? i.second.mean_t / i.second.n_calls : 0, 1,
174  false);
175 
176  stats_text += format(
177  "%s %7u %6s%c %6s%c %6s%c %6s%c\n",
178  aux_format_string_multilines(i.first, 39).c_str(),
179  static_cast<unsigned int>(i.second.n_calls), sMinT.c_str(),
180  i.second.has_time_units ? 's' : ' ', sMeanT.c_str(),
181  i.second.has_time_units ? 's' : ' ', sMaxT.c_str(),
182  i.second.has_time_units ? 's' : ' ', sTotalT.c_str(),
183  i.second.has_time_units ? 's' : ' ');
184  }
185 
186  std::string footer(top_header);
187  stats_text += footer + "\n";
188 
189  return stats_text;
190 }
191 
192 void CTimeLogger::saveToCSVFile(const std::string& csv_file) const
193 {
194  std::string s;
195  s += "FUNCTION, #CALLS, LAST.T, MIN.T, MEAN.T, MAX.T, TOTAL.T\n";
196  for (const auto& i : m_data)
197  {
198  s += format(
199  "\"%s\",\"%7u\",\"%e\",\"%e\",\"%e\",\"%e\",\"%e\"\n",
200  i.first.c_str(), static_cast<unsigned int>(i.second.n_calls),
201  i.second.last_t, i.second.min_t,
202  i.second.n_calls ? i.second.mean_t / i.second.n_calls : 0,
203  i.second.max_t, i.second.mean_t);
204  }
205  CFileOutputStream(csv_file).printf("%s", s.c_str());
206 }
207 
208 void CTimeLogger::dumpAllStats(const size_t column_width) const
209 {
210  MRPT_LOG_INFO_STREAM("dumpAllStats:\n" << getStatsAsText(column_width));
211 }
212 
213 void CTimeLogger::do_enter(const char* func_name)
214 {
215  const string s = func_name;
216  TCallData& d = m_data[s];
217 
218  d.n_calls++;
219  d.open_calls.push(0); // Dummy value, it'll be written below
220  d.open_calls.top() = m_tictac.Tac(); // to avoid possible delays.
221 }
222 
223 double CTimeLogger::do_leave(const char* func_name)
224 {
225  const double tim = m_tictac.Tac();
226 
227  const string s = func_name;
228  TCallData& d = m_data[s];
229 
230  if (!d.open_calls.empty())
231  {
232  const double At = tim - d.open_calls.top();
233  d.open_calls.pop();
234 
235  d.last_t = At;
236  d.mean_t += At;
237  if (d.n_calls == 1)
238  {
239  d.min_t = At;
240  d.max_t = At;
241  }
242  else
243  {
246  }
247  return At;
248  }
249  else
250  return 0; // This shouldn't happen!
251 }
252 
254  const char* event_name, const double value)
255 {
256  if (!m_enabled) return;
257  const string s = event_name;
258  TCallData& d = m_data[s];
259 
260  d.has_time_units = false;
261  d.last_t = value;
262  d.mean_t += value;
263  if (++d.n_calls == 1)
264  {
265  d.min_t = value;
266  d.max_t = value;
267  }
268  else
269  {
272  }
273 }
274 
276  : n_calls(0), min_t(0), max_t(0), mean_t(0), last_t(0), has_time_units(true)
277 {
278 }
279 
281 {
283  if (it == m_data.end())
284  return 0;
285  else
286  return it->second.n_calls ? it->second.mean_t / it->second.n_calls : 0;
287 }
289 {
291  if (it == m_data.end())
292  return 0;
293  else
294  return it->second.last_t;
295 }
296 
298  const CTimeLogger& logger, const char* section_name)
299  : m_logger(const_cast<CTimeLogger&>(logger)), m_section_name(section_name)
300 {
302 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
void getStats(std::map< std::string, TCallStats > &out_stats) const
Returns all the current stats as a map: section_name => stats.
std::stack< double, std::vector< double > > open_calls
Definition: CTimeLogger.h:59
void global_profiler_leave(const char *func_name) noexcept
Definition: CTimeLogger.cpp:48
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
GLdouble s
Definition: glext.h:3676
GLenum GLsizei len
Definition: glext.h:4712
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
MyGlobalProfiler global_profiler
Definition: CTimeLogger.cpp:37
void clear(bool deep_clear=false)
Resets all stats.
CTimeLogger & operator=(const CTimeLogger &o)
Definition: CTimeLogger.cpp:76
This CStream derived class allow using a file as a write-only, binary stream.
Data of all the calls:
Definition: CTimeLogger.h:53
CTimeLogger(bool enabled=true, const std::string &name="")
Definition: CTimeLogger.cpp:55
std::string getStatsAsText(const size_t column_width=80) const
Dump all stats to a multi-line text string.
void saveToCSVFile(const std::string &csv_file) const
Dump all stats to a Comma Separated Values (CSV) file.
double do_leave(const char *func_name)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
void do_enter(const char *func_name)
Data of each call section: # of calls, minimum, maximum, average and overall execution time (in secon...
Definition: CTimeLogger.h:75
double getLastTime(const std::string &name) const
Return the last execution time of the given "section", or 0 if it hasn&#39;t ever been called "enter" wit...
virtual ~CTimeLogger()
Default constructor.
Definition: CTimeLogger.cpp:62
GLsizei const GLchar ** string
Definition: glext.h:4101
CTimeLoggerEntry(const CTimeLogger &logger, const char *section_name)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void global_profiler_enter(const char *func_name) noexcept
Definition: CTimeLogger.cpp:44
#define MRPT_LOG_INFO_STREAM(__CONTENTS)
~CTimeLoggerEntry()
std::string unitsFormat(const double val, int nDecimalDigits=2, bool middle_space=true)
This function implements formatting with the appropriate SI metric unit prefix: 1e-12->&#39;p&#39;, 1e-9->&#39;n&#39;, 1e-6->&#39;u&#39;, 1e-3->&#39;m&#39;, 1->&#39;&#39;, 1e3->&#39;K&#39;, 1e6->&#39;M&#39;, 1e9->&#39;G&#39;, 1e12->&#39;T&#39;.
std::string aux_format_string_multilines(const std::string &s, const size_t len)
double getMeanTime(const std::string &name) const
Return the mean execution time of the given "section", or 0 if it hasn&#39;t ever been called "enter" wit...
GLuint const GLchar * name
Definition: glext.h:4054
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
Definition: CTimeLogger.h:45
double leave(const char *func_name)
End of a named section.
Definition: CTimeLogger.h:123
const char * m_section_name
Definition: CTimeLogger.h:157
std::string rightPad(const std::string &str, const size_t total_len, bool truncate_if_larger=false)
Enlarge the string with spaces up to the given length.
void registerUserMeasure(const char *event_name, const double value)
CTimeLogger & m_logger
Definition: CTimeLogger.h:156
GLsizei const GLfloat * value
Definition: glext.h:4117
void enter(const char *func_name)
Start of a named section.
Definition: CTimeLogger.h:117
GLfloat GLfloat p
Definition: glext.h:6305
void dumpAllStats(const size_t column_width=80) const
Dump all stats through the COutputLogger interface.
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
mrpt::utils::CTimeLogger & global_profiler_getref() noexcept
Definition: CTimeLogger.cpp:43
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
Definition: CStream.cpp:597



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019