00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef LEMON_TIME_MEASURE_H
00020 #define LEMON_TIME_MEASURE_H
00021
00025
00026 #include <sys/time.h>
00027 #include <sys/times.h>
00028 #include <fstream>
00029 #include <iostream>
00030 #include <unistd.h>
00031
00032 namespace lemon {
00033
00036
00038
00053
00054 class TimeStamp
00055 {
00056 struct rtms
00057 {
00058 double tms_utime;
00059 double tms_stime;
00060 double tms_cutime;
00061 double tms_cstime;
00062 rtms() {}
00063 rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
00064 tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
00065 };
00066 rtms ts;
00067 double real_time;
00068
00069 rtms &getTms() {return ts;}
00070 const rtms &getTms() const {return ts;}
00071
00072 void _reset()
00073 { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
00074
00075 public:
00076
00078 void stamp()
00079 {
00080 timeval tv;
00081 tms _ts;
00082 times(&_ts);
00083 gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
00084 ts=_ts;
00085 }
00086
00088 TimeStamp()
00089 { _reset(); }
00091 TimeStamp(void *) { stamp();}
00092
00094 TimeStamp &reset() {_reset();return *this;}
00095
00097 TimeStamp &operator+=(const TimeStamp &b)
00098 {
00099 ts.tms_utime+=b.ts.tms_utime;
00100 ts.tms_stime+=b.ts.tms_stime;
00101 ts.tms_cutime+=b.ts.tms_cutime;
00102 ts.tms_cstime+=b.ts.tms_cstime;
00103 real_time+=b.real_time;
00104 return *this;
00105 }
00107 TimeStamp operator+(const TimeStamp &b) const
00108 {
00109 TimeStamp t(*this);
00110 return t+=b;
00111 }
00113 TimeStamp &operator-=(const TimeStamp &b)
00114 {
00115 ts.tms_utime-=b.ts.tms_utime;
00116 ts.tms_stime-=b.ts.tms_stime;
00117 ts.tms_cutime-=b.ts.tms_cutime;
00118 ts.tms_cstime-=b.ts.tms_cstime;
00119 real_time-=b.real_time;
00120 return *this;
00121 }
00123 TimeStamp operator-(const TimeStamp &b) const
00124 {
00125 TimeStamp t(*this);
00126 return t-=b;
00127 }
00129 TimeStamp &operator*=(double b)
00130 {
00131 ts.tms_utime*=b;
00132 ts.tms_stime*=b;
00133 ts.tms_cutime*=b;
00134 ts.tms_cstime*=b;
00135 real_time*=b;
00136 return *this;
00137 }
00139 TimeStamp operator*(double b) const
00140 {
00141 TimeStamp t(*this);
00142 return t*=b;
00143 }
00144 friend TimeStamp operator*(double b,const TimeStamp &t);
00146 TimeStamp &operator/=(double b)
00147 {
00148 ts.tms_utime/=b;
00149 ts.tms_stime/=b;
00150 ts.tms_cutime/=b;
00151 ts.tms_cstime/=b;
00152 real_time/=b;
00153 return *this;
00154 }
00156 TimeStamp operator/(double b) const
00157 {
00158 TimeStamp t(*this);
00159 return t/=b;
00160 }
00162 TimeStamp ellapsed() const
00163 {
00164 TimeStamp t(NULL);
00165 return t-*this;
00166 }
00167
00168 friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
00169
00171 double userTime() const
00172 {
00173 return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
00174 }
00176 double systemTime() const
00177 {
00178 return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
00179 }
00181 double cUserTime() const
00182 {
00183 return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
00184 }
00186 double cSystemTime() const
00187 {
00188 return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
00189 }
00191 double realTime() const {return real_time;}
00192 };
00193
00194 TimeStamp operator*(double b,const TimeStamp &t)
00195 {
00196 return t*b;
00197 }
00198
00200
00212 inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
00213 {
00214 long cls = sysconf(_SC_CLK_TCK);
00215 os << "u: " << double(t.getTms().tms_utime)/cls <<
00216 "s, s: " << double(t.getTms().tms_stime)/cls <<
00217 "s, cu: " << double(t.getTms().tms_cutime)/cls <<
00218 "s, cs: " << double(t.getTms().tms_cstime)/cls <<
00219 "s, real: " << t.realTime() << "s";
00220 return os;
00221 }
00222
00224
00266 class Timer
00267 {
00268 int _running;
00269 TimeStamp start_time;
00270
00271
00272 void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
00273
00274 public:
00276
00279 Timer(bool run=true) :_running(run) {_reset();}
00280
00289
00291
00293
00296 void reset()
00297 {
00298 _running=0;
00299 _reset();
00300 }
00301
00303
00309 void start()
00310 {
00311 if(_running) _running++;
00312 else {
00313 _running=1;
00314 TimeStamp t;
00315 t.stamp();
00316 start_time=t-start_time;
00317 }
00318 }
00319
00320
00322
00331
00332 void stop()
00333 {
00334 if(_running && !--_running) {
00335 TimeStamp t;
00336 t.stamp();
00337 start_time=t-start_time;
00338 }
00339 }
00340
00342
00348
00349 void halt()
00350 {
00351 if(_running) {
00352 _running=0;
00353 TimeStamp t;
00354 t.stamp();
00355 start_time=t-start_time;
00356 }
00357 }
00358
00360
00367 int running() { return _running; }
00368
00369
00371
00375 void restart()
00376 {
00377 reset();
00378 start();
00379 }
00380
00382
00384
00386
00388 double userTime() const
00389 {
00390 return operator TimeStamp().userTime();
00391 }
00393 double systemTime() const
00394 {
00395 return operator TimeStamp().systemTime();
00396 }
00398 double cUserTime() const
00399 {
00400 return operator TimeStamp().cUserTime();
00401 }
00403 double cSystemTime() const
00404 {
00405 return operator TimeStamp().cSystemTime();
00406 }
00408 double realTime() const
00409 {
00410 return operator TimeStamp().realTime();
00411 }
00413
00421 operator TimeStamp () const
00422 {
00423 TimeStamp t;
00424 t.stamp();
00425 return _running?t-start_time:start_time;
00426 }
00427
00428
00430 };
00431
00433
00447 class TimeReport : public Timer
00448 {
00449 std::string _title;
00450 std::ostream &_os;
00451 public:
00453
00457
00458 TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
00459 : Timer(run), _title(title), _os(os){}
00461 ~TimeReport()
00462 {
00463 _os << _title << *this << std::endl;
00464 }
00465 };
00466
00468
00471 class NoTimeReport
00472 {
00473 public:
00475 NoTimeReport(std::string,std::ostream &,bool) {}
00477 NoTimeReport(std::string,std::ostream &) {}
00479 NoTimeReport(std::string) {}
00481 ~NoTimeReport() {}
00482
00483 operator TimeStamp () const { return TimeStamp(); }
00484 void reset() {}
00485 void start() {}
00486 void stop() {}
00487 void halt() {}
00488 int running() { return 0; }
00489 void restart() {}
00490 double userTime() const { return 0; }
00491 double systemTime() const { return 0; }
00492 double cUserTime() const { return 0; }
00493 double cSystemTime() const { return 0; }
00494 double realTime() const { return 0; }
00495 };
00496
00498
00510
00511 template<class F>
00512 TimeStamp runningTimeTest(F f,double min_time=10,int *num = NULL,
00513 TimeStamp *full_time=NULL)
00514 {
00515 Timer t;
00516 TimeStamp full;
00517 int total=0;
00518 for(int tn=1;tn < 1<<24; tn*=2) {
00519 for(;total<tn;total++) f();
00520 full=t;
00521 if(full.realTime()>min_time) {
00522 if(num) *num=total;
00523 if(full_time) *full_time=full;
00524 return full/total;
00525 }
00526 }
00527 return TimeStamp();
00528 }
00529
00531
00532
00533 }
00534
00535 #endif //LEMON_TIME_MEASURE_H