lemon/time_measure.h
changeset 1849 a4d1362397fe
parent 1839 b2dfd32b4895
child 1850 50d1d6acfcc2
equal deleted inserted replaced
5:17b697332983 6:d46c4a64e3e9
    15  */
    15  */
    16 
    16 
    17 #ifndef LEMON_TIME_MEASURE_H
    17 #ifndef LEMON_TIME_MEASURE_H
    18 #define LEMON_TIME_MEASURE_H
    18 #define LEMON_TIME_MEASURE_H
    19 
    19 
    20 ///\ingroup misc
    20 ///\ingroup timecount
    21 ///\file
    21 ///\file
    22 ///\brief Tools for measuring cpu usage
    22 ///\brief Tools for measuring cpu usage
    23 
    23 
    24 #include <sys/time.h>
    24 #include <sys/time.h>
    25 #include <sys/times.h>
    25 #include <sys/times.h>
    27 #include <iostream>
    27 #include <iostream>
    28 #include <unistd.h>
    28 #include <unistd.h>
    29 
    29 
    30 namespace lemon {
    30 namespace lemon {
    31 
    31 
    32   /// \addtogroup misc
    32   /// \addtogroup timecount
    33   /// @{
    33   /// @{
    34 
    34 
    35   /// A class to store (cpu)time instances.
    35   /// A class to store (cpu)time instances.
    36 
    36 
    37   /// This class stores five time values.
    37   /// This class stores five time values.
   207   ///  ...
   207   ///  ...
   208   ///
   208   ///
   209   ///  Timer T;
   209   ///  Timer T;
   210   ///  doSomething();
   210   ///  doSomething();
   211   ///  std::cout << T << '\n';
   211   ///  std::cout << T << '\n';
   212   ///  T.reset();
   212   ///  T.restart();
   213   ///  doSomethingElse();
   213   ///  doSomethingElse();
   214   ///  std::cout << T << '\n';
   214   ///  std::cout << T << '\n';
   215   ///
   215   ///
   216   ///  ...
   216   ///  ...
   217   ///
   217   ///
   221   ///The \ref Timer can also be \ref stop() "stopped" and
   221   ///The \ref Timer can also be \ref stop() "stopped" and
   222   ///\ref start() "started" again, so it is possible to compute collected
   222   ///\ref start() "started" again, so it is possible to compute collected
   223   ///running times.
   223   ///running times.
   224   ///
   224   ///
   225   ///\warning Depending on the operation system and its actual configuration
   225   ///\warning Depending on the operation system and its actual configuration
   226   ///the time counters have a certain (relatively big) granularity.
   226   ///the time counters have a certain (10ms on a typical Linux system)
       
   227   ///granularity.
   227   ///Therefore this tool is not appropriate to measure very short times.
   228   ///Therefore this tool is not appropriate to measure very short times.
   228   ///Also, if you start and stop the timer very frequently, it could lead
   229   ///Also, if you start and stop the timer very frequently, it could lead
   229   ///distorted results.
   230   ///distorted results.
   230   ///
   231   ///
   231   ///The \ref Timer also counts the number of \ref start()
   232   ///The \ref Timer also counts the number of \ref start()
   236   ///\todo This shouldn't be Unix (Linux) specific.
   237   ///\todo This shouldn't be Unix (Linux) specific.
   237   ///
   238   ///
   238   ///\author Alpar Juttner
   239   ///\author Alpar Juttner
   239   class Timer
   240   class Timer
   240   {
   241   {
   241     int running; //Timer is running iff running>0; (running>=0 always holds)
   242     int _running; //Timer is running iff _running>0; (_running>=0 always holds)
   242     TimeStamp start_time; //This is the relativ start-time if the timer
   243     TimeStamp start_time; //This is the relativ start-time if the timer
   243                           //is running, the collected running time otherwise.
   244                           //is _running, the collected _running time otherwise.
   244     
   245     
   245     void _reset() {if(running) start_time.stamp(); else start_time.reset();}
   246     void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
   246   
   247   
   247   public: 
   248   public: 
   248     ///Constructor.
   249     ///Constructor.
   249 
   250 
   250     ///\param _running indicates whether or not the timer starts immediately.
   251     ///\param _running indicates whether or not the timer starts immediately.
   251     ///
   252     ///
   252     Timer(bool _running=true) :running(_running) {_reset();}
   253     Timer(bool run=true) :_running(run) {_reset();}
   253 
   254 
   254     ///Computes the ellapsed time
   255     ///Computes the ellapsed time
   255 
   256 
   256     ///This conversion computes the ellapsed time
   257     ///This conversion computes the ellapsed time
   257     ///
   258     ///
   258     operator TimeStamp () const
   259     operator TimeStamp () const
   259     {
   260     {
   260       TimeStamp t;
   261       TimeStamp t;
   261       t.stamp();
   262       t.stamp();
   262       return running?t-start_time:start_time;
   263       return _running?t-start_time:start_time;
   263     }
   264     }
   264 
   265 
   265     ///Resets the time counters
   266     ///Reset and stop the time counters
   266 
   267 
   267     ///Resets the time counters
   268     ///This function resets and stops the time counters
   268     ///
   269     ///\sa restart()
   269     void reset()
   270     void reset()
   270     {
   271     {
       
   272       _running=0;
   271       _reset();
   273       _reset();
   272     }
   274     }
   273 
   275 
   274     ///Start the time counters
   276     ///Start the time counters
   275     
   277     
   278     ///If the timer is started more than ones, it will remain running
   280     ///If the timer is started more than ones, it will remain running
   279     ///until the same amount of \ref stop() is called.
   281     ///until the same amount of \ref stop() is called.
   280     ///\sa stop()
   282     ///\sa stop()
   281     void start() 
   283     void start() 
   282     {
   284     {
   283       if(running) running++;
   285       if(_running) _running++;
   284       else {
   286       else {
   285 	TimeStamp t;
   287 	TimeStamp t;
   286 	t.stamp();
   288 	t.stamp();
   287 	start_time=t-start_time;
   289 	start_time=t-start_time;
   288       }
   290       }
   289     }
   291     }
       
   292 
   290     
   293     
   291     ///Stop the time counters
   294     ///Stop the time counters
   292 
   295 
   293     ///This function stops the time counters.
   296     ///This function stops the time counters. If start() was executed more than
   294     ///
   297     ///once, then the same number of stop() execution is necessary the really
   295     ///\sa stop()
   298     ///stop the timer.
       
   299     /// 
       
   300     ///\sa halt()
       
   301     ///\sa start()
       
   302     ///\sa restart()
       
   303     ///\sa reset()
       
   304 
   296     void stop() 
   305     void stop() 
   297     {
   306     {
   298       if(running && !--running) {
   307       if(_running && !--_running) {
   299 	TimeStamp t;
   308 	TimeStamp t;
   300 	t.stamp();
   309 	t.stamp();
   301 	start_time=t-start_time;
   310 	start_time=t-start_time;
   302       }
   311       }
   303     }
   312     }
       
   313 
       
   314     ///Halt (i.e stop immediately) the time counters
       
   315 
       
   316     ///This function stops immediately the time counters.
       
   317     ///
       
   318     ///\sa stop()
       
   319     ///\sa restart()
       
   320     ///\sa reset()
       
   321 
       
   322     void halt() 
       
   323     {
       
   324       if(_running) {
       
   325 	_running=0;
       
   326 	TimeStamp t;
       
   327 	t.stamp();
       
   328 	start_time=t-start_time;
       
   329       }
       
   330     }
       
   331 
       
   332     ///Returns the running state of the timer
       
   333 
       
   334     ///This function returns the number of stop() exections that is
       
   335     ///necessary to really stop the timer.
       
   336     ///For example the timer
       
   337     ///is running if and only if the return value is \c true
       
   338     ///(i.e. greater than
       
   339     ///zero).
       
   340     int running()  { return _running; }
       
   341     
       
   342     
       
   343     ///Restart the time counters
       
   344 
       
   345     ///This function is a shorthand for
       
   346     ///a reset() and a start() calls.
       
   347     ///
       
   348     void restart() 
       
   349     {
       
   350       reset();
       
   351       start();
       
   352     }
   304     
   353     
   305     ///Gives back the ellapsed user time of the process
   354     ///Gives back the ellapsed user time of the process
   306     double userTime() const
   355     double userTime() const
   307     {
   356     {
   308       return operator TimeStamp().userTime();
   357       return operator TimeStamp().userTime();
   328       return operator TimeStamp().realTime();
   377       return operator TimeStamp().realTime();
   329     }
   378     }
   330 
   379 
   331   };
   380   };
   332 
   381 
       
   382   ///Same as \ref Timer but prints a report on destruction.
       
   383 
       
   384   ///Same as \ref Timer but prints a report on destruction.
       
   385   ///\todo Untested
       
   386   class TimeReport : public Timer 
       
   387   {
       
   388     std::string _title;
       
   389     std::ostream &_os;
       
   390   public:
       
   391     ///\e
       
   392     
       
   393     TimeReport(std::string title,std::ostream &os,bool run) 
       
   394       : Timer(run), _title(title), _os(os){}
       
   395     ~TimeReport() 
       
   396     {
       
   397       _os << _title << this << std::endl;
       
   398     }
       
   399   };
       
   400       
   333   ///Prints the time counters
   401   ///Prints the time counters
   334 
   402 
   335   ///Prints the time counters in the following form:
   403   ///Prints the time counters in the following form:
   336   ///
   404   ///
   337   /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
   405   /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>