Merge
authorAlpar Juttner <alpar@cs.elte.hu>
Sat, 12 Apr 2008 19:42:38 +0100
changeset 12235840c5aa696
parent 118 407c08a0eae9
parent 121 91c0fed3181e
child 124 ae7785fe8431
Merge
     1.1 --- a/lemon/Makefile.am	Fri Apr 11 16:20:54 2008 +0200
     1.2 +++ b/lemon/Makefile.am	Sat Apr 12 19:42:38 2008 +0100
     1.3 @@ -20,6 +20,7 @@
     1.4  	lemon/assert.h \
     1.5          lemon/bfs.h \
     1.6          lemon/bin_heap.h \
     1.7 +        lemon/counter.h \
     1.8          lemon/dfs.h \
     1.9          lemon/dijkstra.h \
    1.10          lemon/dim2.h \
    1.11 @@ -32,6 +33,7 @@
    1.12  	lemon/path.h \
    1.13          lemon/random.h \
    1.14  	lemon/smart_graph.h \
    1.15 +        lemon/time_measure.h \
    1.16          lemon/tolerance.h \
    1.17  	lemon/unionfind.h
    1.18  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/lemon/counter.h	Sat Apr 12 19:42:38 2008 +0100
     2.3 @@ -0,0 +1,181 @@
     2.4 +/* -*- C++ -*-
     2.5 + *
     2.6 + * This file is a part of LEMON, a generic C++ optimization library
     2.7 + *
     2.8 + * Copyright (C) 2003-2008
     2.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    2.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    2.11 + *
    2.12 + * Permission to use, modify and distribute this software is granted
    2.13 + * provided that this copyright notice appears in all copies. For
    2.14 + * precise terms see the accompanying LICENSE file.
    2.15 + *
    2.16 + * This software is provided "AS IS" with no warranty of any kind,
    2.17 + * express or implied, and with no claim as to its suitability for any
    2.18 + * purpose.
    2.19 + *
    2.20 + */
    2.21 +
    2.22 +#ifndef LEMON_COUNTER_H
    2.23 +#define LEMON_COUNTER_H
    2.24 +
    2.25 +#include <string>
    2.26 +#include <iostream>
    2.27 +
    2.28 +///\ingroup timecount
    2.29 +///\file
    2.30 +///\brief Tools for counting steps and events
    2.31 +
    2.32 +namespace lemon 
    2.33 +{
    2.34 +
    2.35 +  template<class P> class _NoSubCounter;
    2.36 +
    2.37 +  template<class P>
    2.38 +  class _SubCounter 
    2.39 +  {
    2.40 +    P &_parent;
    2.41 +    std::string _title;
    2.42 +    std::ostream &_os;
    2.43 +    int count;
    2.44 +  public:
    2.45 +
    2.46 +    typedef _SubCounter<_SubCounter<P> > SubCounter;
    2.47 +    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
    2.48 +
    2.49 +    _SubCounter(P &parent)
    2.50 +      : _parent(parent), _title(), _os(std::cerr), count(0) {}
    2.51 +    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
    2.52 +      : _parent(parent), _title(title), _os(os), count(0) {}
    2.53 +    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
    2.54 +      : _parent(parent), _title(title), _os(os), count(0) {}
    2.55 +    ~_SubCounter() { 
    2.56 +      _os << _title << count <<std::endl;
    2.57 +      _parent+=count;
    2.58 +    }
    2.59 +    _SubCounter &operator++() { count++; return *this;}
    2.60 +    int operator++(int) { return count++; }
    2.61 +    _SubCounter &operator--() { count--; return *this;}
    2.62 +    int operator--(int) { return count--; }
    2.63 +    _SubCounter &operator+=(int c) { count+=c; return *this;}
    2.64 +    _SubCounter &operator-=(int c) { count-=c; return *this;}
    2.65 +    void reset(int c=0) {count=c;}
    2.66 +    operator int() {return count;}
    2.67 +  };
    2.68 +
    2.69 +  template<class P>
    2.70 +  class _NoSubCounter 
    2.71 +  {
    2.72 +    P &_parent;
    2.73 +  public:
    2.74 +    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
    2.75 +    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
    2.76 +  
    2.77 +    _NoSubCounter(P &parent) :_parent(parent) {}
    2.78 +    _NoSubCounter(P &parent,std::string,std::ostream &) 
    2.79 +      :_parent(parent) {}
    2.80 +    _NoSubCounter(P &parent,std::string) 
    2.81 +      :_parent(parent) {}
    2.82 +    _NoSubCounter(P &parent,const char *,std::ostream &)
    2.83 +      :_parent(parent) {}
    2.84 +    _NoSubCounter(P &parent,const char *)
    2.85 +      :_parent(parent) {}
    2.86 +    ~_NoSubCounter() {}
    2.87 +    _NoSubCounter &operator++() { ++_parent; return *this;}
    2.88 +    int operator++(int) { _parent++; return 0;}
    2.89 +    _NoSubCounter &operator--() { --_parent; return *this;}
    2.90 +    int operator--(int) { _parent--; return 0;}
    2.91 +    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
    2.92 +    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
    2.93 +    void reset(int) {}
    2.94 +    void reset() {}
    2.95 +    operator int() {return 0;}
    2.96 +  };
    2.97 +
    2.98 +
    2.99 +  /// \addtogroup timecount
   2.100 +  /// @{
   2.101 +
   2.102 +  ///A counter class
   2.103 +
   2.104 +  ///This class makes it easier to count certain events. You can increment
   2.105 +  ///or decrement the counter using operator++ and operator--.
   2.106 +  ///A report is automatically printed on destruction.
   2.107 +  ///\todo More doc
   2.108 +  class Counter 
   2.109 +  {
   2.110 +    std::string _title;
   2.111 +    std::ostream &_os;
   2.112 +    int count;
   2.113 +  public:
   2.114 +    ///\e
   2.115 +
   2.116 +    ///\todo document please.
   2.117 +    ///
   2.118 +    typedef _SubCounter<Counter> SubCounter;
   2.119 +    ///\e
   2.120 +
   2.121 +    ///\todo document please.
   2.122 +    ///
   2.123 +    typedef _NoSubCounter<Counter> NoSubCounter;
   2.124 +
   2.125 +    ///\e
   2.126 +    Counter() : _title(), _os(std::cerr), count(0) {}
   2.127 +    ///\e
   2.128 +    Counter(std::string title,std::ostream &os=std::cerr) 
   2.129 +      : _title(title), _os(os), count(0) {}
   2.130 +    ///\e
   2.131 +    Counter(const char *title,std::ostream &os=std::cerr)
   2.132 +      : _title(title), _os(os), count(0) {}
   2.133 +    ///Destructor. Prints the given title and the value of the counter.
   2.134 +    ~Counter() {
   2.135 +      _os << _title << count <<std::endl;
   2.136 +    }
   2.137 +    ///\e
   2.138 +    Counter &operator++() { count++; return *this;}
   2.139 +    ///\e
   2.140 +    int operator++(int) { return count++;}
   2.141 +    ///\e
   2.142 +    Counter &operator--() { count--; return *this;}
   2.143 +    ///\e
   2.144 +    int operator--(int) { return count--;}
   2.145 +    ///\e
   2.146 +    Counter &operator+=(int c) { count+=c; return *this;}
   2.147 +    ///\e
   2.148 +    Counter &operator-=(int c) { count-=c; return *this;}
   2.149 +    ///\e
   2.150 +    void reset(int c=0) {count=c;}
   2.151 +    ///\e
   2.152 +    operator int() {return count;}
   2.153 +  };
   2.154 +
   2.155 +  ///'Do nothing' version of \ref Counter
   2.156 +
   2.157 +  ///'Do nothing' version of \ref Counter.
   2.158 +  ///\sa Counter
   2.159 +  class NoCounter
   2.160 +  {
   2.161 +  public:
   2.162 +    typedef _NoSubCounter<NoCounter> SubCounter;
   2.163 +    typedef _NoSubCounter<NoCounter> NoSubCounter;
   2.164 +
   2.165 +    NoCounter() {}
   2.166 +    NoCounter(std::string,std::ostream &) {}
   2.167 +    NoCounter(const char *,std::ostream &) {}
   2.168 +    NoCounter(std::string) {}
   2.169 +    NoCounter(const char *) {}
   2.170 +    NoCounter &operator++() { return *this; }
   2.171 +    int operator++(int) { return 0; }
   2.172 +    NoCounter &operator--() { return *this; }
   2.173 +    int operator--(int) { return 0; }
   2.174 +    NoCounter &operator+=(int) { return *this;}
   2.175 +    NoCounter &operator-=(int) { return *this;}
   2.176 +    void reset(int) {}
   2.177 +    void reset() {}
   2.178 +    operator int() {return 0;}
   2.179 +  };
   2.180 +
   2.181 +  ///@}
   2.182 +}
   2.183 +
   2.184 +#endif
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/lemon/time_measure.h	Sat Apr 12 19:42:38 2008 +0100
     3.3 @@ -0,0 +1,541 @@
     3.4 +/* -*- C++ -*-
     3.5 + *
     3.6 + * This file is a part of LEMON, a generic C++ optimization library
     3.7 + *
     3.8 + * Copyright (C) 2003-2008
     3.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    3.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    3.11 + *
    3.12 + * Permission to use, modify and distribute this software is granted
    3.13 + * provided that this copyright notice appears in all copies. For
    3.14 + * precise terms see the accompanying LICENSE file.
    3.15 + *
    3.16 + * This software is provided "AS IS" with no warranty of any kind,
    3.17 + * express or implied, and with no claim as to its suitability for any
    3.18 + * purpose.
    3.19 + *
    3.20 + */
    3.21 +
    3.22 +#ifndef LEMON_TIME_MEASURE_H
    3.23 +#define LEMON_TIME_MEASURE_H
    3.24 +
    3.25 +///\ingroup timecount
    3.26 +///\file
    3.27 +///\brief Tools for measuring cpu usage
    3.28 +
    3.29 +#include <sys/times.h>
    3.30 +
    3.31 +#include <sys/time.h>
    3.32 +#include <fstream>
    3.33 +#include <iostream>
    3.34 +#include <unistd.h>
    3.35 +
    3.36 +namespace lemon {
    3.37 +
    3.38 +  /// \addtogroup timecount
    3.39 +  /// @{
    3.40 +
    3.41 +  /// A class to store (cpu)time instances.
    3.42 +
    3.43 +  /// This class stores five time values.
    3.44 +  /// - a real time
    3.45 +  /// - a user cpu time
    3.46 +  /// - a system cpu time
    3.47 +  /// - a user cpu time of children
    3.48 +  /// - a system cpu time of children
    3.49 +  ///
    3.50 +  /// TimeStamp's can be added to or substracted from each other and
    3.51 +  /// they can be pushed to a stream.
    3.52 +  ///
    3.53 +  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
    3.54 +  /// class is what you want to use instead.
    3.55 +  ///
    3.56 +  ///\author Alpar Juttner
    3.57 +
    3.58 +  class TimeStamp
    3.59 +  {
    3.60 +    struct rtms 
    3.61 +    {
    3.62 +      double tms_utime;
    3.63 +      double tms_stime;
    3.64 +      double tms_cutime;
    3.65 +      double tms_cstime;
    3.66 +      rtms() {}
    3.67 +      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
    3.68 +		     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
    3.69 +    };
    3.70 +    rtms ts;
    3.71 +    double real_time;
    3.72 +  
    3.73 +    rtms &getTms() {return ts;}
    3.74 +    const rtms &getTms() const {return ts;}
    3.75 +
    3.76 +    void _reset() { 
    3.77 +      ts.tms_utime = ts.tms_stime = ts.tms_cutime = ts.tms_cstime = 0; 
    3.78 +      real_time = 0;
    3.79 +    }
    3.80 +
    3.81 +  public:
    3.82 +
    3.83 +    ///Read the current time values of the process
    3.84 +    void stamp()
    3.85 +    {
    3.86 +      timeval tv;
    3.87 +      tms _ts;
    3.88 +      times(&_ts);
    3.89 +      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
    3.90 +      ts=_ts;
    3.91 +    }
    3.92 +  
    3.93 +    /// Constructor initializing with zero
    3.94 +    TimeStamp()
    3.95 +    { _reset(); }
    3.96 +    ///Constructor initializing with the current time values of the process
    3.97 +    TimeStamp(void *) { stamp();}
    3.98 +  
    3.99 +    ///Set every time value to zero
   3.100 +    TimeStamp &reset() {_reset();return *this;}
   3.101 +
   3.102 +    ///\e
   3.103 +    TimeStamp &operator+=(const TimeStamp &b)
   3.104 +    {
   3.105 +      ts.tms_utime+=b.ts.tms_utime;
   3.106 +      ts.tms_stime+=b.ts.tms_stime;
   3.107 +      ts.tms_cutime+=b.ts.tms_cutime;
   3.108 +      ts.tms_cstime+=b.ts.tms_cstime;
   3.109 +      real_time+=b.real_time;
   3.110 +      return *this;
   3.111 +    }
   3.112 +    ///\e
   3.113 +    TimeStamp operator+(const TimeStamp &b) const
   3.114 +    {
   3.115 +      TimeStamp t(*this);
   3.116 +      return t+=b;
   3.117 +    }
   3.118 +    ///\e
   3.119 +    TimeStamp &operator-=(const TimeStamp &b)
   3.120 +    {
   3.121 +      ts.tms_utime-=b.ts.tms_utime;
   3.122 +      ts.tms_stime-=b.ts.tms_stime;
   3.123 +      ts.tms_cutime-=b.ts.tms_cutime;
   3.124 +      ts.tms_cstime-=b.ts.tms_cstime;
   3.125 +      real_time-=b.real_time;
   3.126 +      return *this;
   3.127 +    }
   3.128 +    ///\e
   3.129 +    TimeStamp operator-(const TimeStamp &b) const
   3.130 +    {
   3.131 +      TimeStamp t(*this);
   3.132 +      return t-=b;
   3.133 +    }
   3.134 +    ///\e
   3.135 +    TimeStamp &operator*=(double b)
   3.136 +    {
   3.137 +      ts.tms_utime*=b;
   3.138 +      ts.tms_stime*=b;
   3.139 +      ts.tms_cutime*=b;
   3.140 +      ts.tms_cstime*=b;
   3.141 +      real_time*=b;
   3.142 +      return *this;
   3.143 +    }
   3.144 +    ///\e
   3.145 +    TimeStamp operator*(double b) const
   3.146 +    {
   3.147 +      TimeStamp t(*this);
   3.148 +      return t*=b;
   3.149 +    }
   3.150 +    friend TimeStamp operator*(double b,const TimeStamp &t);
   3.151 +    ///\e
   3.152 +    TimeStamp &operator/=(double b)
   3.153 +    {
   3.154 +      ts.tms_utime/=b;
   3.155 +      ts.tms_stime/=b;
   3.156 +      ts.tms_cutime/=b;
   3.157 +      ts.tms_cstime/=b;
   3.158 +      real_time/=b;
   3.159 +      return *this;
   3.160 +    }
   3.161 +    ///\e
   3.162 +    TimeStamp operator/(double b) const
   3.163 +    {
   3.164 +      TimeStamp t(*this);
   3.165 +      return t/=b;
   3.166 +    }
   3.167 +    ///The time ellapsed since the last call of stamp()
   3.168 +    TimeStamp ellapsed() const
   3.169 +    {
   3.170 +      TimeStamp t(NULL);
   3.171 +      return t-*this;
   3.172 +    }
   3.173 +  
   3.174 +    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
   3.175 +  
   3.176 +    ///Gives back the user time of the process
   3.177 +    double userTime() const
   3.178 +    {
   3.179 +      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
   3.180 +    }
   3.181 +    ///Gives back the system time of the process
   3.182 +    double systemTime() const
   3.183 +    {
   3.184 +      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
   3.185 +    }
   3.186 +    ///Gives back the user time of the process' children
   3.187 +    double cUserTime() const
   3.188 +    {
   3.189 +      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
   3.190 +    }
   3.191 +    ///Gives back the user time of the process' children
   3.192 +    double cSystemTime() const
   3.193 +    {
   3.194 +      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
   3.195 +    }
   3.196 +    ///Gives back the real time
   3.197 +    double realTime() const {return real_time;}
   3.198 +  };
   3.199 +
   3.200 +  TimeStamp operator*(double b,const TimeStamp &t) 
   3.201 +  {
   3.202 +    return t*b;
   3.203 +  }
   3.204 +  
   3.205 +  ///Prints the time counters
   3.206 +
   3.207 +  ///Prints the time counters in the following form:
   3.208 +  ///
   3.209 +  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
   3.210 +  ///
   3.211 +  /// where the values are the
   3.212 +  /// \li \c u: user cpu time,
   3.213 +  /// \li \c s: system cpu time,
   3.214 +  /// \li \c cu: user cpu time of children,
   3.215 +  /// \li \c cs: system cpu time of children,
   3.216 +  /// \li \c real: real time.
   3.217 +  /// \relates TimeStamp
   3.218 +  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
   3.219 +  {
   3.220 +    long cls = sysconf(_SC_CLK_TCK);
   3.221 +    os << "u: " << double(t.getTms().tms_utime)/cls <<
   3.222 +      "s, s: " << double(t.getTms().tms_stime)/cls <<
   3.223 +      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
   3.224 +      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
   3.225 +      "s, real: " << t.realTime() << "s";
   3.226 +    return os;
   3.227 +  }
   3.228 +
   3.229 +  ///Class for measuring the cpu time and real time usage of the process
   3.230 +
   3.231 +  ///Class for measuring the cpu time and real time usage of the process.
   3.232 +  ///It is quite easy-to-use, here is a short example.
   3.233 +  ///\code
   3.234 +  /// #include<lemon/time_measure.h>
   3.235 +  /// #include<iostream>
   3.236 +  ///
   3.237 +  /// int main()
   3.238 +  /// {
   3.239 +  ///
   3.240 +  ///   ...
   3.241 +  ///
   3.242 +  ///   Timer t;
   3.243 +  ///   doSomething();
   3.244 +  ///   std::cout << t << '\n';
   3.245 +  ///   t.restart();
   3.246 +  ///   doSomethingElse();
   3.247 +  ///   std::cout << t << '\n';
   3.248 +  ///
   3.249 +  ///   ...
   3.250 +  ///
   3.251 +  /// }
   3.252 +  ///\endcode
   3.253 +  ///
   3.254 +  ///The \ref Timer can also be \ref stop() "stopped" and
   3.255 +  ///\ref start() "started" again, so it is possible to compute collected
   3.256 +  ///running times.
   3.257 +  ///
   3.258 +  ///\warning Depending on the operation system and its actual configuration
   3.259 +  ///the time counters have a certain (10ms on a typical Linux system)
   3.260 +  ///granularity.
   3.261 +  ///Therefore this tool is not appropriate to measure very short times.
   3.262 +  ///Also, if you start and stop the timer very frequently, it could lead to
   3.263 +  ///distorted results.
   3.264 +  ///
   3.265 +  ///\note If you want to measure the running time of the execution of a certain
   3.266 +  ///function, consider the usage of \ref TimeReport instead.
   3.267 +  ///
   3.268 +  ///\todo This shouldn't be Unix (Linux) specific.
   3.269 +  ///\sa TimeReport
   3.270 +  ///
   3.271 +  ///\author Alpar Juttner
   3.272 +  class Timer
   3.273 +  {
   3.274 +    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
   3.275 +    TimeStamp start_time; //This is the relativ start-time if the timer
   3.276 +                          //is _running, the collected _running time otherwise.
   3.277 +    
   3.278 +    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
   3.279 +  
   3.280 +  public: 
   3.281 +    ///Constructor.
   3.282 +
   3.283 +    ///\param run indicates whether or not the timer starts immediately.
   3.284 +    ///
   3.285 +    Timer(bool run=true) :_running(run) {_reset();}
   3.286 +
   3.287 +    ///\name Control the state of the timer
   3.288 +    ///Basically a Timer can be either running or stopped,
   3.289 +    ///but it provides a bit finer control on the execution.
   3.290 +    ///The \ref Timer also counts the number of \ref start()
   3.291 +    ///executions, and is stops only after the same amount (or more)
   3.292 +    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
   3.293 +    ///of recursive functions.
   3.294 +    ///
   3.295 +
   3.296 +    ///@{
   3.297 +
   3.298 +    ///Reset and stop the time counters
   3.299 +
   3.300 +    ///This function resets and stops the time counters
   3.301 +    ///\sa restart()
   3.302 +    void reset()
   3.303 +    {
   3.304 +      _running=0;
   3.305 +      _reset();
   3.306 +    }
   3.307 +
   3.308 +    ///Start the time counters
   3.309 +    
   3.310 +    ///This function starts the time counters.
   3.311 +    ///
   3.312 +    ///If the timer is started more than ones, it will remain running
   3.313 +    ///until the same amount of \ref stop() is called.
   3.314 +    ///\sa stop()
   3.315 +    void start() 
   3.316 +    {
   3.317 +      if(_running) _running++;
   3.318 +      else {
   3.319 +	_running=1;
   3.320 +	TimeStamp t;
   3.321 +	t.stamp();
   3.322 +	start_time=t-start_time;
   3.323 +      }
   3.324 +    }
   3.325 +
   3.326 +    
   3.327 +    ///Stop the time counters
   3.328 +
   3.329 +    ///This function stops the time counters. If start() was executed more than
   3.330 +    ///once, then the same number of stop() execution is necessary the really
   3.331 +    ///stop the timer.
   3.332 +    /// 
   3.333 +    ///\sa halt()
   3.334 +    ///\sa start()
   3.335 +    ///\sa restart()
   3.336 +    ///\sa reset()
   3.337 +
   3.338 +    void stop() 
   3.339 +    {
   3.340 +      if(_running && !--_running) {
   3.341 +	TimeStamp t;
   3.342 +	t.stamp();
   3.343 +	start_time=t-start_time;
   3.344 +      }
   3.345 +    }
   3.346 +
   3.347 +    ///Halt (i.e stop immediately) the time counters
   3.348 +
   3.349 +    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
   3.350 +    ///is a faster
   3.351 +    ///equivalent of the following.
   3.352 +    ///\code
   3.353 +    ///  while(t.running()) t.stop()
   3.354 +    ///\endcode
   3.355 +    ///
   3.356 +    ///
   3.357 +    ///\sa stop()
   3.358 +    ///\sa restart()
   3.359 +    ///\sa reset()
   3.360 +
   3.361 +    void halt() 
   3.362 +    {
   3.363 +      if(_running) {
   3.364 +	_running=0;
   3.365 +	TimeStamp t;
   3.366 +	t.stamp();
   3.367 +	start_time=t-start_time;
   3.368 +      }
   3.369 +    }
   3.370 +
   3.371 +    ///Returns the running state of the timer
   3.372 +
   3.373 +    ///This function returns the number of stop() exections that is
   3.374 +    ///necessary to really stop the timer.
   3.375 +    ///For example the timer
   3.376 +    ///is running if and only if the return value is \c true
   3.377 +    ///(i.e. greater than
   3.378 +    ///zero).
   3.379 +    int running()  { return _running; }
   3.380 +    
   3.381 +    
   3.382 +    ///Restart the time counters
   3.383 +
   3.384 +    ///This function is a shorthand for
   3.385 +    ///a reset() and a start() calls.
   3.386 +    ///
   3.387 +    void restart() 
   3.388 +    {
   3.389 +      reset();
   3.390 +      start();
   3.391 +    }
   3.392 +    
   3.393 +    ///@}
   3.394 +
   3.395 +    ///\name Query Functions for the ellapsed time
   3.396 +
   3.397 +    ///@{
   3.398 +
   3.399 +    ///Gives back the ellapsed user time of the process
   3.400 +    double userTime() const
   3.401 +    {
   3.402 +      return operator TimeStamp().userTime();
   3.403 +    }
   3.404 +    ///Gives back the ellapsed system time of the process
   3.405 +    double systemTime() const
   3.406 +    {
   3.407 +      return operator TimeStamp().systemTime();
   3.408 +    }
   3.409 +    ///Gives back the ellapsed user time of the process' children
   3.410 +    double cUserTime() const
   3.411 +    {
   3.412 +      return operator TimeStamp().cUserTime();
   3.413 +    }
   3.414 +    ///Gives back the ellapsed user time of the process' children
   3.415 +    double cSystemTime() const
   3.416 +    {
   3.417 +      return operator TimeStamp().cSystemTime();
   3.418 +    }
   3.419 +    ///Gives back the ellapsed real time
   3.420 +    double realTime() const
   3.421 +    {
   3.422 +      return operator TimeStamp().realTime();
   3.423 +    }
   3.424 +    ///Computes the ellapsed time
   3.425 +
   3.426 +    ///This conversion computes the ellapsed time, therefore you can print
   3.427 +    ///the ellapsed time like this.
   3.428 +    ///\code
   3.429 +    ///  Timer t;
   3.430 +    ///  doSomething();
   3.431 +    ///  std::cout << t << '\n';
   3.432 +    ///\endcode
   3.433 +    operator TimeStamp () const
   3.434 +    {
   3.435 +      TimeStamp t;
   3.436 +      t.stamp();
   3.437 +      return _running?t-start_time:start_time;
   3.438 +    }
   3.439 +
   3.440 +
   3.441 +    ///@}
   3.442 +  };
   3.443 +
   3.444 +  ///Same as \ref Timer but prints a report on destruction.
   3.445 +
   3.446 +  ///Same as \ref Timer but prints a report on destruction.
   3.447 +  ///This example shows its usage.
   3.448 +  ///\code
   3.449 +  ///  void myAlg(ListGraph &g,int n)
   3.450 +  ///  {
   3.451 +  ///    TimeReport tr("Running time of myAlg: ");
   3.452 +  ///    ... //Here comes the algorithm
   3.453 +  ///  }
   3.454 +  ///\endcode
   3.455 +  ///
   3.456 +  ///\sa Timer
   3.457 +  ///\sa NoTimeReport
   3.458 +  ///\todo There is no test case for this
   3.459 +  class TimeReport : public Timer 
   3.460 +  {
   3.461 +    std::string _title;
   3.462 +    std::ostream &_os;
   3.463 +  public:
   3.464 +    ///\e
   3.465 +
   3.466 +    ///\param title This text will be printed before the ellapsed time.
   3.467 +    ///\param os The stream to print the report to.
   3.468 +    ///\param run Sets whether the timer should start immediately.
   3.469 +
   3.470 +    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
   3.471 +      : Timer(run), _title(title), _os(os){}
   3.472 +    ///\e Prints the ellapsed time on destruction.
   3.473 +    ~TimeReport() 
   3.474 +    {
   3.475 +      _os << _title << *this << std::endl;
   3.476 +    }
   3.477 +  };
   3.478 +      
   3.479 +  ///'Do nothing' version of \ref TimeReport
   3.480 +
   3.481 +  ///\sa TimeReport
   3.482 +  ///
   3.483 +  class NoTimeReport
   3.484 +  {
   3.485 +  public:
   3.486 +    ///\e
   3.487 +    NoTimeReport(std::string,std::ostream &,bool) {}
   3.488 +    ///\e
   3.489 +    NoTimeReport(std::string,std::ostream &) {}
   3.490 +    ///\e
   3.491 +    NoTimeReport(std::string) {}
   3.492 +    ///\e Do nothing.
   3.493 +    ~NoTimeReport() {}
   3.494 +
   3.495 +    operator TimeStamp () const { return TimeStamp(); }
   3.496 +    void reset() {}
   3.497 +    void start() {}
   3.498 +    void stop() {}
   3.499 +    void halt() {} 
   3.500 +    int running() { return 0; }
   3.501 +    void restart() {}
   3.502 +    double userTime() const { return 0; }
   3.503 +    double systemTime() const { return 0; }
   3.504 +    double cUserTime() const { return 0; }
   3.505 +    double cSystemTime() const { return 0; }
   3.506 +    double realTime() const { return 0; }
   3.507 +  };
   3.508 +      
   3.509 +  ///Tool to measure the running time more exactly.
   3.510 +  
   3.511 +  ///This function calls \c f several times and returns the average
   3.512 +  ///running time. The number of the executions will be choosen in such a way
   3.513 +  ///that the full real running time will be roughly between \c min_time
   3.514 +  ///and <tt>2*min_time</tt>.
   3.515 +  ///\param f the function object to be measured.
   3.516 +  ///\param min_time the minimum total running time.
   3.517 +  ///\retval num if it is not \c NULL, then the actual
   3.518 +  ///        number of execution of \c f will be written into <tt>*num</tt>.
   3.519 +  ///\retval full_time if it is not \c NULL, then the actual
   3.520 +  ///        total running time will be written into <tt>*full_time</tt>.
   3.521 +  ///\return The average running time of \c f.
   3.522 +  
   3.523 +  template<class F>
   3.524 +  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
   3.525 +                            TimeStamp *full_time=NULL)
   3.526 +  {
   3.527 +    TimeStamp full;
   3.528 +    unsigned int total=0;
   3.529 +    Timer t;
   3.530 +    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
   3.531 +      for(;total<tn;total++) f();
   3.532 +      full=t;
   3.533 +    }
   3.534 +    if(num) *num=total;
   3.535 +    if(full_time) *full_time=full;
   3.536 +    return full/total;
   3.537 +  }
   3.538 +  
   3.539 +  /// @}  
   3.540 +
   3.541 +
   3.542 +} //namespace lemon
   3.543 +
   3.544 +#endif //LEMON_TIME_MEASURE_H
     4.1 --- a/test/Makefile.am	Fri Apr 11 16:20:54 2008 +0200
     4.2 +++ b/test/Makefile.am	Sat Apr 12 19:42:38 2008 +0100
     4.3 @@ -9,6 +9,7 @@
     4.4  
     4.5  check_PROGRAMS += \
     4.6  	test/bfs_test \
     4.7 +        test/counter_test \
     4.8  	test/dfs_test \
     4.9  	test/digraph_test \
    4.10          test/dim_test \
    4.11 @@ -20,12 +21,14 @@
    4.12          test/path_test \
    4.13          test/test_tools_fail \
    4.14          test/test_tools_pass \
    4.15 +        test/time_measure_test \
    4.16  	test/unionfind_test
    4.17  
    4.18  TESTS += $(check_PROGRAMS)
    4.19  XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
    4.20  
    4.21  test_bfs_test_SOURCES = test/bfs_test.cc
    4.22 +test_counter_test_SOURCES = test/counter_test.cc
    4.23  test_dfs_test_SOURCES = test/dfs_test.cc
    4.24  test_digraph_test_SOURCES = test/digraph_test.cc
    4.25  test_dim_test_SOURCES = test/dim_test.cc
    4.26 @@ -38,4 +41,5 @@
    4.27  test_random_test_SOURCES = test/random_test.cc
    4.28  test_test_tools_fail_SOURCES = test/test_tools_fail.cc
    4.29  test_test_tools_pass_SOURCES = test/test_tools_pass.cc
    4.30 +test_time_measure_test_SOURCES = test/time_measure_test.cc
    4.31  test_unionfind_test_SOURCES = test/unionfind_test.cc
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/counter_test.cc	Sat Apr 12 19:42:38 2008 +0100
     5.3 @@ -0,0 +1,66 @@
     5.4 +/* -*- C++ -*-
     5.5 + *
     5.6 + * This file is a part of LEMON, a generic C++ optimization library
     5.7 + *
     5.8 + * Copyright (C) 2003-2008
     5.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    5.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    5.11 + *
    5.12 + * Permission to use, modify and distribute this software is granted
    5.13 + * provided that this copyright notice appears in all copies. For
    5.14 + * precise terms see the accompanying LICENSE file.
    5.15 + *
    5.16 + * This software is provided "AS IS" with no warranty of any kind,
    5.17 + * express or implied, and with no claim as to its suitability for any
    5.18 + * purpose.
    5.19 + *
    5.20 + */
    5.21 +
    5.22 +#include <lemon/counter.h>
    5.23 +
    5.24 +///\file \brief Test cases for time_measure.h
    5.25 +///
    5.26 +///\todo To be extended
    5.27 +
    5.28 +
    5.29 +int fibonacci(int f) 
    5.30 +{
    5.31 +  static lemon::Counter count("Fibonacci steps: ");
    5.32 +  count++;
    5.33 +  if(f<1) return 0;
    5.34 +  else if(f==1) return 1;
    5.35 +  else return fibonacci(f-1)+fibonacci(f-2);
    5.36 +}
    5.37 +
    5.38 +int main()
    5.39 +{
    5.40 +  fibonacci(10);
    5.41 +  
    5.42 +  {  
    5.43 +    typedef lemon::Counter MyCounter;
    5.44 +    MyCounter c("Main counter: ");
    5.45 +    c++;
    5.46 +    c++;
    5.47 +    MyCounter::SubCounter d(c,"Subcounter: ");
    5.48 +    d++;
    5.49 +    d++;
    5.50 +    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
    5.51 +    e++;
    5.52 +    e++;
    5.53 +  }
    5.54 +  
    5.55 +  {
    5.56 +    typedef lemon::NoCounter MyCounter;
    5.57 +    MyCounter c("Main counter: ");
    5.58 +    c++;
    5.59 +    c++;
    5.60 +    MyCounter::SubCounter d(c,"Subcounter: ");
    5.61 +    d++;
    5.62 +    d++;
    5.63 +    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
    5.64 +    e++;
    5.65 +    e++;
    5.66 +  }
    5.67 +
    5.68 +  return 0;
    5.69 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/time_measure_test.cc	Sat Apr 12 19:42:38 2008 +0100
     6.3 @@ -0,0 +1,63 @@
     6.4 +/* -*- C++ -*-
     6.5 + *
     6.6 + * This file is a part of LEMON, a generic C++ optimization library
     6.7 + *
     6.8 + * Copyright (C) 2003-2008
     6.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    6.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    6.11 + *
    6.12 + * Permission to use, modify and distribute this software is granted
    6.13 + * provided that this copyright notice appears in all copies. For
    6.14 + * precise terms see the accompanying LICENSE file.
    6.15 + *
    6.16 + * This software is provided "AS IS" with no warranty of any kind,
    6.17 + * express or implied, and with no claim as to its suitability for any
    6.18 + * purpose.
    6.19 + *
    6.20 + */
    6.21 +
    6.22 +#include <lemon/time_measure.h>
    6.23 +
    6.24 +///\file \brief Test cases for time_measure.h
    6.25 +///
    6.26 +///\todo To be extended
    6.27 +
    6.28 +
    6.29 +using namespace lemon;
    6.30 +
    6.31 +void f() 
    6.32 +{
    6.33 +  double d=0;
    6.34 +  for(int i=0;i<1000;i++)
    6.35 +    d+=0.1;
    6.36 +}
    6.37 +
    6.38 +void g() 
    6.39 +{
    6.40 +  static Timer T;
    6.41 +  
    6.42 +  for(int i=0;i<1000;i++)
    6.43 +    TimeStamp x(T);
    6.44 +}
    6.45 +
    6.46 +int main()
    6.47 +{
    6.48 +  Timer T;
    6.49 +  unsigned int n;
    6.50 +  for(n=0;T.realTime()<1.0;n++) ;
    6.51 +  std::cout << T << " (" << n << " time queries)\n";
    6.52 +  T.restart();
    6.53 +  while(T.realTime()<2.0) ;
    6.54 +  std::cout << T << '\n';
    6.55 +  TimeStamp full;
    6.56 +  TimeStamp t;
    6.57 +  t=runningTimeTest(f,1,&n,&full);
    6.58 +  std::cout << t << " (" << n << " tests)\n";
    6.59 +  std::cout << "Total: " << full << "\n";
    6.60 +  
    6.61 +  t=runningTimeTest(g,1,&n,&full);
    6.62 +  std::cout << t << " (" << n << " tests)\n";
    6.63 +  std::cout << "Total: " << full << "\n";
    6.64 +  
    6.65 +  return 0;
    6.66 +}