time_measure.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
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; //Timer is running iff _running>0; (_running>=0 always holds)
00269     TimeStamp start_time; //This is the relativ start-time if the timer
00270                           //is _running, the collected _running time otherwise.
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 } //namespace lemon
00534 
00535 #endif //LEMON_TIME_MEASURE_H

Generated on Fri Feb 3 18:39:50 2006 for LEMON by  doxygen 1.4.6