1.1 --- a/lemon/Makefile.am Sat Mar 29 15:49:50 2008 +0000
1.2 +++ b/lemon/Makefile.am Sun Mar 30 22:16:35 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 Sun Mar 30 22:16:35 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 _SubNoCounter;
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 _SubNoCounter<_SubCounter<P> > SubNoCounter;
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 _SubNoCounter
2.71 + {
2.72 + P &_parent;
2.73 + public:
2.74 + typedef _SubNoCounter<_SubNoCounter<P> > SubCounter;
2.75 + typedef _SubNoCounter<_SubNoCounter<P> > SubNoCounter;
2.76 +
2.77 + _SubNoCounter(P &parent) :_parent(parent) {}
2.78 + _SubNoCounter(P &parent,std::string,std::ostream &)
2.79 + :_parent(parent) {}
2.80 + _SubNoCounter(P &parent,std::string)
2.81 + :_parent(parent) {}
2.82 + _SubNoCounter(P &parent,const char *,std::ostream &)
2.83 + :_parent(parent) {}
2.84 + _SubNoCounter(P &parent,const char *)
2.85 + :_parent(parent) {}
2.86 + ~_SubNoCounter() {}
2.87 + _SubNoCounter &operator++() { ++_parent; return *this;}
2.88 + int operator++(int) { _parent++; return 0;}
2.89 + _SubNoCounter &operator--() { --_parent; return *this;}
2.90 + int operator--(int) { _parent--; return 0;}
2.91 + _SubNoCounter &operator+=(int c) { _parent+=c; return *this;}
2.92 + _SubNoCounter &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 _SubNoCounter<Counter> SubNoCounter;
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 _SubNoCounter<NoCounter> SubCounter;
2.163 + typedef _SubNoCounter<NoCounter> SubNoCounter;
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 Sun Mar 30 22:16:35 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.stop()</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 Sat Mar 29 15:49:50 2008 +0000
4.2 +++ b/test/Makefile.am Sun Mar 30 22:16:35 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 Sun Mar 30 22:16:35 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 Sun Mar 30 22:16:35 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 +}