Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef FCL_UTIL_PROFILER
00039 #define FCL_UTIL_PROFILER
00040
00041 #define ENABLE_PROFILING 1
00042
00043 #ifndef ENABLE_PROFILING
00044
00046
00047 # ifdef NDEBUG
00048 # define ENABLE_PROFILING 0
00049 # else
00050 # define ENABLE_PROFILING 1
00051 # endif
00052
00053 #endif
00054
00055 #if ENABLE_PROFILING
00056
00057 #include <map>
00058 #include <string>
00059 #include <iostream>
00060 #include <boost/thread.hpp>
00061 #include <boost/noncopyable.hpp>
00062 #include <boost/date_time/posix_time/posix_time.hpp>
00063
00064 namespace fcl
00065 {
00066
00068 namespace time
00069 {
00070
00072 typedef boost::posix_time::ptime point;
00073
00075 typedef boost::posix_time::time_duration duration;
00076
00078 inline point now(void)
00079 {
00080 return boost::posix_time::microsec_clock::universal_time();
00081 }
00082
00084 inline duration seconds(double sec)
00085 {
00086 long s = (long)sec;
00087 long us = (long)((sec - s) * 1000000);
00088 return boost::posix_time::seconds(s) + boost::posix_time::microseconds(us);
00089 }
00090
00092 inline double seconds(const duration &d)
00093 {
00094 return (double)d.total_microseconds() / 1000000.0;
00095 }
00096
00097 }
00098
00099 namespace tools
00100 {
00101
00107 class Profiler : private boost::noncopyable
00108 {
00109 public:
00110
00112 class ScopedBlock
00113 {
00114 public:
00116 ScopedBlock(const std::string &name, Profiler &prof = Profiler::Instance()) : name_(name), prof_(prof)
00117 {
00118 prof_.begin(name);
00119 }
00120
00121 ~ScopedBlock(void)
00122 {
00123 prof_.end(name_);
00124 }
00125
00126 private:
00127
00128 std::string name_;
00129 Profiler &prof_;
00130 };
00131
00134 class ScopedStart
00135 {
00136 public:
00137
00139 ScopedStart(Profiler &prof = Profiler::Instance()) : prof_(prof), wasRunning_(prof_.running())
00140 {
00141 if (!wasRunning_)
00142 prof_.start();
00143 }
00144
00145 ~ScopedStart(void)
00146 {
00147 if (!wasRunning_)
00148 prof_.stop();
00149 }
00150
00151 private:
00152
00153 Profiler &prof_;
00154 bool wasRunning_;
00155 };
00156
00158 static Profiler& Instance(void);
00159
00162 Profiler(bool printOnDestroy = false, bool autoStart = false) : running_(false), printOnDestroy_(printOnDestroy)
00163 {
00164 if (autoStart)
00165 start();
00166 }
00167
00169 ~Profiler(void)
00170 {
00171 if (printOnDestroy_ && !data_.empty())
00172 status();
00173 }
00174
00176 static void Start(void)
00177 {
00178 Instance().start();
00179 }
00180
00182 static void Stop(void)
00183 {
00184 Instance().stop();
00185 }
00186
00188 static void Clear(void)
00189 {
00190 Instance().clear();
00191 }
00192
00194 void start(void);
00195
00197 void stop(void);
00198
00200 void clear(void);
00201
00203 static void Event(const std::string& name, const unsigned int times = 1)
00204 {
00205 Instance().event(name, times);
00206 }
00207
00209 void event(const std::string &name, const unsigned int times = 1);
00210
00212 static void Average(const std::string& name, const double value)
00213 {
00214 Instance().average(name, value);
00215 }
00216
00218 void average(const std::string &name, const double value);
00219
00221 static void Begin(const std::string &name)
00222 {
00223 Instance().begin(name);
00224 }
00225
00227 static void End(const std::string &name)
00228 {
00229 Instance().end(name);
00230 }
00231
00233 void begin(const std::string &name);
00234
00236 void end(const std::string &name);
00237
00241 static void Status(std::ostream &out = std::cout, bool merge = true)
00242 {
00243 Instance().status(out, merge);
00244 }
00245
00249 void status(std::ostream &out = std::cout, bool merge = true);
00250
00252 bool running(void) const
00253 {
00254 return running_;
00255 }
00256
00258 static bool Running(void)
00259 {
00260 return Instance().running();
00261 }
00262
00263 private:
00264
00266 struct TimeInfo
00267 {
00268 TimeInfo(void) : total(0, 0, 0, 0), shortest(boost::posix_time::pos_infin), longest(boost::posix_time::neg_infin), parts(0)
00269 {
00270 }
00271
00273 time::duration total;
00274
00276 time::duration shortest;
00277
00279 time::duration longest;
00280
00282 unsigned long int parts;
00283
00285 time::point start;
00286
00288 void set(void)
00289 {
00290 start = time::now();
00291 }
00292
00294 void update(void)
00295 {
00296 const time::duration &dt = time::now() - start;
00297 if (dt > longest)
00298 longest = dt;
00299 if (dt < shortest)
00300 shortest = dt;
00301 total = total + dt;
00302 ++parts;
00303 }
00304 };
00305
00307 struct AvgInfo
00308 {
00310 double total;
00311
00313 double totalSqr;
00314
00316 unsigned long int parts;
00317 };
00318
00320 struct PerThread
00321 {
00323 std::map<std::string, unsigned long int> events;
00324
00326 std::map<std::string, AvgInfo> avg;
00327
00329 std::map<std::string, TimeInfo> time;
00330 };
00331
00332 void printThreadInfo(std::ostream &out, const PerThread &data);
00333
00334 boost::mutex lock_;
00335 std::map<boost::thread::id, PerThread> data_;
00336 TimeInfo tinfo_;
00337 bool running_;
00338 bool printOnDestroy_;
00339
00340 };
00341 }
00342 }
00343
00344 #else
00345
00346 #include <string>
00347 #include <iostream>
00348
00350 namespace fcl
00351 {
00352
00353 namespace tools
00354 {
00355
00356 class Profiler
00357 {
00358 public:
00359
00360 class ScopedBlock
00361 {
00362 public:
00363
00364 ScopedBlock(const std::string &, Profiler & = Profiler::Instance())
00365 {
00366 }
00367
00368 ~ScopedBlock(void)
00369 {
00370 }
00371 };
00372
00373 class ScopedStart
00374 {
00375 public:
00376
00377 ScopedStart(Profiler & = Profiler::Instance())
00378 {
00379 }
00380
00381 ~ScopedStart(void)
00382 {
00383 }
00384 };
00385
00386 static Profiler& Instance(void);
00387
00388 Profiler(bool = true, bool = true)
00389 {
00390 }
00391
00392 ~Profiler(void)
00393 {
00394 }
00395
00396 static void Start(void)
00397 {
00398 }
00399
00400 static void Stop(void)
00401 {
00402 }
00403
00404 static void Clear(void)
00405 {
00406 }
00407
00408 void start(void)
00409 {
00410 }
00411
00412 void stop(void)
00413 {
00414 }
00415
00416 void clear(void)
00417 {
00418 }
00419
00420 static void Event(const std::string&, const unsigned int = 1)
00421 {
00422 }
00423
00424 void event(const std::string &, const unsigned int = 1)
00425 {
00426 }
00427
00428 static void Average(const std::string&, const double)
00429 {
00430 }
00431
00432 void average(const std::string &, const double)
00433 {
00434 }
00435
00436 static void Begin(const std::string &)
00437 {
00438 }
00439
00440 static void End(const std::string &)
00441 {
00442 }
00443
00444 void begin(const std::string &)
00445 {
00446 }
00447
00448 void end(const std::string &)
00449 {
00450 }
00451
00452 static void Status(std::ostream & = std::cout, bool = true)
00453 {
00454 }
00455
00456 void status(std::ostream & = std::cout, bool = true)
00457 {
00458 }
00459
00460 bool running(void) const
00461 {
00462 return false;
00463 }
00464
00465 static bool Running(void)
00466 {
00467 return false;
00468 }
00469 };
00470 }
00471 }
00472
00473 #endif
00474
00475 #endif