lemon/time_measure.h
changeset 1854 a68d4f93b1fb
parent 1850 50d1d6acfcc2
child 1855 c72636dcf0bd
equal deleted inserted replaced
7:3d9d7d983853 8:df78175e3129
    42   /// - a system cpu time of children
    42   /// - a system cpu time of children
    43   ///
    43   ///
    44   /// TimeStamp's can be added to or substracted from each other and
    44   /// TimeStamp's can be added to or substracted from each other and
    45   /// they can be pushed to a stream.
    45   /// they can be pushed to a stream.
    46   ///
    46   ///
    47   /// In most cases, perhaps \ref Timer class is what you want to use instead.
    47   /// In most cases, perhaps the \ref Timer or the \ref TimeReport
       
    48   /// class is what you want to use instead.
    48   ///
    49   ///
    49   ///\author Alpar Juttner
    50   ///\author Alpar Juttner
    50 
    51 
    51   class TimeStamp
    52   class TimeStamp
    52   {
    53   {
   191   TimeStamp operator*(double b,const TimeStamp &t) 
   192   TimeStamp operator*(double b,const TimeStamp &t) 
   192   {
   193   {
   193     return t*b;
   194     return t*b;
   194   }
   195   }
   195   
   196   
       
   197   ///Prints the time counters
       
   198 
       
   199   ///Prints the time counters in the following form:
       
   200   ///
       
   201   /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
       
   202   ///
       
   203   /// where the values are the
       
   204   /// \li \c u: user cpu time,
       
   205   /// \li \c s: system cpu time,
       
   206   /// \li \c cu: user cpu time of children,
       
   207   /// \li \c cs: system cpu time of children,
       
   208   /// \li \c real: real time.
       
   209   /// \relates TimeStamp
       
   210   inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
       
   211   {
       
   212     long cls = sysconf(_SC_CLK_TCK);
       
   213     os << "u: " << double(t.getTms().tms_utime)/cls <<
       
   214       "s, s: " << double(t.getTms().tms_stime)/cls <<
       
   215       "s, cu: " << double(t.getTms().tms_cutime)/cls <<
       
   216       "s, cs: " << double(t.getTms().tms_cstime)/cls <<
       
   217       "s, real: " << t.realTime() << "s";
       
   218     return os;
       
   219   }
       
   220 
   196   ///Class for measuring the cpu time and real time usage of the process
   221   ///Class for measuring the cpu time and real time usage of the process
   197 
   222 
   198   ///Class for measuring the cpu time and real time usage of the process.
   223   ///Class for measuring the cpu time and real time usage of the process.
   199   ///It is quite easy-to-use, here is a short example.
   224   ///It is quite easy-to-use, here is a short example.
   200   ///\code
   225   ///\code
   227   ///granularity.
   252   ///granularity.
   228   ///Therefore this tool is not appropriate to measure very short times.
   253   ///Therefore this tool is not appropriate to measure very short times.
   229   ///Also, if you start and stop the timer very frequently, it could lead
   254   ///Also, if you start and stop the timer very frequently, it could lead
   230   ///distorted results.
   255   ///distorted results.
   231   ///
   256   ///
   232   ///The \ref Timer also counts the number of \ref start()
   257   ///\note If you want to measure the running time of the execution of a certain
   233   ///executions, and is stops only after the same amount (or more)
   258   ///function, consider the usage of \ref TimeReport instead.
   234   ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
       
   235   ///of recursive functions.
       
   236   ///
   259   ///
   237   ///\todo This shouldn't be Unix (Linux) specific.
   260   ///\todo This shouldn't be Unix (Linux) specific.
       
   261   ///\sa TimeReport
   238   ///
   262   ///
   239   ///\author Alpar Juttner
   263   ///\author Alpar Juttner
   240   class Timer
   264   class Timer
   241   {
   265   {
   242     int _running; //Timer is running iff _running>0; (_running>=0 always holds)
   266     int _running; //Timer is running iff _running>0; (_running>=0 always holds)
   250 
   274 
   251     ///\param _running indicates whether or not the timer starts immediately.
   275     ///\param _running indicates whether or not the timer starts immediately.
   252     ///
   276     ///
   253     Timer(bool run=true) :_running(run) {_reset();}
   277     Timer(bool run=true) :_running(run) {_reset();}
   254 
   278 
   255     ///Computes the ellapsed time
   279     ///\name Control the state of the timer
   256 
   280     ///Basically a Timer can be either running or stopped,
   257     ///This conversion computes the ellapsed time
   281     ///but it provides a bit finer control on the execution.
       
   282     ///The \ref Timer also counts the number of \ref start()
       
   283     ///executions, and is stops only after the same amount (or more)
       
   284     ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
       
   285     ///of recursive functions.
   258     ///
   286     ///
   259     operator TimeStamp () const
   287 
   260     {
   288     ///@{
   261       TimeStamp t;
       
   262       t.stamp();
       
   263       return _running?t-start_time:start_time;
       
   264     }
       
   265 
   289 
   266     ///Reset and stop the time counters
   290     ///Reset and stop the time counters
   267 
   291 
   268     ///This function resets and stops the time counters
   292     ///This function resets and stops the time counters
   269     ///\sa restart()
   293     ///\sa restart()
   350     {
   374     {
   351       reset();
   375       reset();
   352       start();
   376       start();
   353     }
   377     }
   354     
   378     
       
   379     ///@}
       
   380 
       
   381     ///\name Query Functions for the ellapsed time
       
   382 
       
   383     ///@{
       
   384 
   355     ///Gives back the ellapsed user time of the process
   385     ///Gives back the ellapsed user time of the process
   356     double userTime() const
   386     double userTime() const
   357     {
   387     {
   358       return operator TimeStamp().userTime();
   388       return operator TimeStamp().userTime();
   359     }
   389     }
   375     ///Gives back the ellapsed real time
   405     ///Gives back the ellapsed real time
   376     double realTime() const
   406     double realTime() const
   377     {
   407     {
   378       return operator TimeStamp().realTime();
   408       return operator TimeStamp().realTime();
   379     }
   409     }
   380 
   410     ///Computes the ellapsed time
       
   411 
       
   412     ///This conversion computes the ellapsed time, therefore you can print
       
   413     ///the ellapsed time like this.
       
   414     ///\code
       
   415     ///  Timer T;
       
   416     ///  doSomething();
       
   417     ///  std::cout << T << '\n';
       
   418     ///\endcode
       
   419     operator TimeStamp () const
       
   420     {
       
   421       TimeStamp t;
       
   422       t.stamp();
       
   423       return _running?t-start_time:start_time;
       
   424     }
       
   425 
       
   426 
       
   427     ///@}
   381   };
   428   };
   382 
   429 
   383   ///Same as \ref Timer but prints a report on destruction.
   430   ///Same as \ref Timer but prints a report on destruction.
   384 
   431 
   385   ///Same as \ref Timer but prints a report on destruction.
   432   ///Same as \ref Timer but prints a report on destruction.
   386   ///\todo Untested
   433   ///This example shows its usage.
       
   434   ///\code
       
   435   ///  void myAlg(ListGraph &g,int n)
       
   436   ///  {
       
   437   ///    TimeReport TR("Running time of myAlg: ");
       
   438   ///    ... //Here comes the algorithm
       
   439   ///  }
       
   440   ///\endcode
       
   441   ///
       
   442   ///\sa Timer
       
   443   ///\sa NoTimeReport
       
   444   ///\todo There is no test case for this
   387   class TimeReport : public Timer 
   445   class TimeReport : public Timer 
   388   {
   446   {
   389     std::string _title;
   447     std::string _title;
   390     std::ostream &_os;
   448     std::ostream &_os;
   391   public:
   449   public:
   392     ///\e
   450     ///\e
   393     
   451 
   394     TimeReport(std::string title,std::ostream &os,bool run) 
   452     ///\param title This text will be printed before the ellapsed time.
       
   453     ///\param os The stream to print the report to.
       
   454     ///\param run Sets whether the timer should start immediately.
       
   455 
       
   456     TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
   395       : Timer(run), _title(title), _os(os){}
   457       : Timer(run), _title(title), _os(os){}
       
   458     ///\e Prints the ellapsed time on destruction.
   396     ~TimeReport() 
   459     ~TimeReport() 
   397     {
   460     {
   398       _os << _title << this << std::endl;
   461       _os << _title << *this << std::endl;
   399     }
   462     }
   400   };
   463   };
   401       
   464       
   402   ///Prints the time counters
   465   ///'Do nothing' version of \ref TimeReport
   403 
   466 
   404   ///Prints the time counters in the following form:
   467   ///\sa TimeReport
   405   ///
   468   ///
   406   /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
   469   class NoTimeReport
   407   ///
   470   {
   408   /// where the values are the
   471   public:
   409   /// \li \c u: user cpu time,
   472     ///\e
   410   /// \li \c s: system cpu time,
   473     NoTimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) {}
   411   /// \li \c cu: user cpu time of children,
   474     ///\e Do nothing.
   412   /// \li \c cs: system cpu time of children,
   475     ~NoTimeReport() {}
   413   /// \li \c real: real time.
   476 
   414   /// \relates TimeStamp
   477     operator TimeStamp () const { return TimeStamp(); }
   415   inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
   478     void reset() {}
   416   {
   479     void start() {}
   417     long cls = sysconf(_SC_CLK_TCK);
   480     void stop() {}
   418     os << "u: " << double(t.getTms().tms_utime)/cls <<
   481     void halt() {} 
   419       "s, s: " << double(t.getTms().tms_stime)/cls <<
   482     int running() { return 0; }
   420       "s, cu: " << double(t.getTms().tms_cutime)/cls <<
   483     void restart() {}
   421       "s, cs: " << double(t.getTms().tms_cstime)/cls <<
   484     double userTime() const { return 0; }
   422       "s, real: " << t.realTime() << "s";
   485     double systemTime() const { return 0; }
   423     return os;
   486     double cUserTime() const { return 0; }
   424   }
   487     double cSystemTime() const { return 0; }
   425 
   488     double realTime() const { return 0; }
   426   
   489   };
       
   490       
   427   ///Tool to measure the running time more exactly.
   491   ///Tool to measure the running time more exactly.
   428   
   492   
   429   ///This function calls \c f several times and returns the average
   493   ///This function calls \c f several times and returns the average
   430   ///running time. The number of the executions will be choosen in such a way
   494   ///running time. The number of the executions will be choosen in such a way
   431   ///that the full real running time will be roughly between \c min_time
   495   ///that the full real running time will be roughly between \c min_time