COIN-OR::LEMON - Graph Library

Ticket #52: time-and-counter.patch

File time-and-counter.patch, 28.1 KB (added by Alpar Juttner, 16 years ago)
  • lemon/Makefile.am

    # HG changeset patch
    # User Alpar Juttner <alpar@cs.elte.hu>
    # Date 1206833667 0
    # Node ID 5711625e85100ef916dbd7fa2718667908044a41
    # Parent  e47fb28cda5ed878df35945a0683dfd8e0075045
    Port time and counter utilities from svn -r3482
    
    diff -r e47fb28cda5e -r 5711625e8510 lemon/Makefile.am
    a b  
    99lemon_libemon_la_SOURCES = \
    1010        lemon/arg_parser.cc \
    1111        lemon/base.cc \
     12        lemon/bits/mingw32_time.cc \
    1213        lemon/random.cc
    1314
    1415
     
    2021        lemon/assert.h \
    2122        lemon/bfs.h \
    2223        lemon/bin_heap.h \
     24        lemon/counter.h \
    2325        lemon/dfs.h \
    2426        lemon/dijkstra.h \
    2527        lemon/dim2.h \
     
    3234        lemon/path.h \
    3335        lemon/random.h \
    3436        lemon/smart_graph.h \
     37        lemon/time_measure.h \
    3538        lemon/tolerance.h \
    3639        lemon/unionfind.h
    3740
     
    4346        lemon/bits/graph_extender.h \
    4447        lemon/bits/invalid.h \
    4548        lemon/bits/map_extender.h \
     49        lemon/bits/mingw32_time.h \
    4650        lemon/bits/path_dump.h \
    4751        lemon/bits/traits.h \
    4852        lemon/bits/utility.h \
  • new file lemon/bits/mingw32_time.cc

    diff -r e47fb28cda5e -r 5711625e8510 lemon/bits/mingw32_time.cc
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#ifdef WIN32
     20
     21#include <lemon/bits/mingw32_time.h>
     22
     23#include <windows.h>
     24#include <ctime>
     25#include "dos.h"
     26
     27int gettimeofday(struct timeval * tp, struct timezone *) {
     28  SYSTEMTIME systime;
     29
     30  if (tp) {
     31    struct tm tmrec;
     32    time_t theTime = time(NULL);
     33   
     34   
     35    tmrec = *localtime(&theTime);
     36    tp->tv_sec = mktime(&tmrec);
     37    GetLocalTime(&systime); /* system time */
     38
     39    tp->tv_usec = systime.wMilliseconds * 1000;
     40  }
     41  return 0;
     42}
     43
     44int times(struct tms *tmbuf)
     45{
     46  FILETIME create, exit, kernel, user;
     47  if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
     48    tmbuf->tms_utime = filetime_to_clock(&user);
     49    tmbuf->tms_stime = filetime_to_clock(&kernel);
     50    tmbuf->tms_cutime = 0;
     51    tmbuf->tms_cstime = 0;
     52  }
     53  else {
     54    tmbuf->tms_utime = clock();
     55    tmbuf->tms_stime = 0;
     56    tmbuf->tms_cutime = 0;
     57    tmbuf->tms_cstime = 0;
     58  }
     59  return 0;
     60}
     61
     62int sysconf(int)
     63{
     64  return 1;
     65}
     66
     67#endif
  • new file lemon/bits/mingw32_time.h

    diff -r e47fb28cda5e -r 5711625e8510 lemon/bits/mingw32_time.h
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#ifndef LEMON_BITS_MINGW32_TIME_H
     20#define LEMON_BITS_MINGW32_TIME_H
     21
     22#ifdef WIN32
     23
     24#include <windows.h>
     25#include <ctime>
     26#include "dos.h"
     27
     28int gettimeofday(struct timeval * tp, struct timezone *);
     29
     30struct tms {
     31  long  tms_utime;
     32  long  tms_stime;
     33  long  tms_cutime;
     34  long  tms_cstime;
     35};
     36
     37int times(struct tms *tmbuf);
     38
     39#define _SC_CLK_TCK 1
     40
     41int sysconf(int);
     42
     43#endif
     44
     45#endif
  • new file lemon/counter.h

    diff -r e47fb28cda5e -r 5711625e8510 lemon/counter.h
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#ifndef LEMON_COUNTER_H
     20#define LEMON_COUNTER_H
     21
     22#include <string>
     23#include <iostream>
     24
     25///\ingroup timecount
     26///\file
     27///\brief Tools for counting steps and events
     28
     29namespace lemon
     30{
     31
     32  template<class P> class _SubNoCounter;
     33
     34  template<class P>
     35  class _SubCounter
     36  {
     37    P &_parent;
     38    std::string _title;
     39    std::ostream &_os;
     40    int count;
     41  public:
     42
     43    typedef _SubCounter<_SubCounter<P> > SubCounter;
     44    typedef _SubNoCounter<_SubCounter<P> > SubNoCounter;
     45
     46    _SubCounter(P &parent)
     47      : _parent(parent), _title(), _os(std::cerr), count(0) {}
     48    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
     49      : _parent(parent), _title(title), _os(os), count(0) {}
     50    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
     51      : _parent(parent), _title(title), _os(os), count(0) {}
     52    ~_SubCounter() {
     53      _os << _title << count <<std::endl;
     54      _parent+=count;
     55    }
     56    _SubCounter &operator++() { count++; return *this;}
     57    int operator++(int) { return count++; }
     58    _SubCounter &operator--() { count--; return *this;}
     59    int operator--(int) { return count--; }
     60    _SubCounter &operator+=(int c) { count+=c; return *this;}
     61    _SubCounter &operator-=(int c) { count-=c; return *this;}
     62    void reset(int c=0) {count=c;}
     63    operator int() {return count;}
     64  };
     65
     66  template<class P>
     67  class _SubNoCounter
     68  {
     69    P &_parent;
     70  public:
     71    typedef _SubNoCounter<_SubNoCounter<P> > SubCounter;
     72    typedef _SubNoCounter<_SubNoCounter<P> > SubNoCounter;
     73 
     74    _SubNoCounter(P &parent) :_parent(parent) {}
     75    _SubNoCounter(P &parent,std::string,std::ostream &)
     76      :_parent(parent) {}
     77    _SubNoCounter(P &parent,std::string)
     78      :_parent(parent) {}
     79    _SubNoCounter(P &parent,const char *,std::ostream &)
     80      :_parent(parent) {}
     81    _SubNoCounter(P &parent,const char *)
     82      :_parent(parent) {}
     83    ~_SubNoCounter() {}
     84    _SubNoCounter &operator++() { ++_parent; return *this;}
     85    int operator++(int) { _parent++; return 0;}
     86    _SubNoCounter &operator--() { --_parent; return *this;}
     87    int operator--(int) { _parent--; return 0;}
     88    _SubNoCounter &operator+=(int c) { _parent+=c; return *this;}
     89    _SubNoCounter &operator-=(int c) { _parent-=c; return *this;}
     90    void reset(int) {}
     91    void reset() {}
     92    operator int() {return 0;}
     93  };
     94
     95
     96  /// \addtogroup timecount
     97  /// @{
     98
     99  ///A counter class
     100
     101  ///This class makes it easier to count certain events. You can increment
     102  ///or decrement the counter using operator++ and operator--.
     103  ///A report is automatically printed on destruction.
     104  ///\todo More doc
     105  class Counter
     106  {
     107    std::string _title;
     108    std::ostream &_os;
     109    int count;
     110  public:
     111    ///\e
     112
     113    ///\todo document please.
     114    ///
     115    typedef _SubCounter<Counter> SubCounter;
     116    ///\e
     117
     118    ///\todo document please.
     119    ///
     120    typedef _SubNoCounter<Counter> SubNoCounter;
     121
     122    ///\e
     123    Counter() : _title(), _os(std::cerr), count(0) {}
     124    ///\e
     125    Counter(std::string title,std::ostream &os=std::cerr)
     126      : _title(title), _os(os), count(0) {}
     127    ///\e
     128    Counter(const char *title,std::ostream &os=std::cerr)
     129      : _title(title), _os(os), count(0) {}
     130    ///Destructor. Prints the given title and the value of the counter.
     131    ~Counter() {
     132      _os << _title << count <<std::endl;
     133    }
     134    ///\e
     135    Counter &operator++() { count++; return *this;}
     136    ///\e
     137    int operator++(int) { return count++;}
     138    ///\e
     139    Counter &operator--() { count--; return *this;}
     140    ///\e
     141    int operator--(int) { return count--;}
     142    ///\e
     143    Counter &operator+=(int c) { count+=c; return *this;}
     144    ///\e
     145    Counter &operator-=(int c) { count-=c; return *this;}
     146    ///\e
     147    void reset(int c=0) {count=c;}
     148    ///\e
     149    operator int() {return count;}
     150  };
     151
     152  ///'Do nothing' version of \ref Counter
     153
     154  ///'Do nothing' version of \ref Counter.
     155  ///\sa Counter
     156  class NoCounter
     157  {
     158  public:
     159    typedef _SubNoCounter<NoCounter> SubCounter;
     160    typedef _SubNoCounter<NoCounter> SubNoCounter;
     161
     162    NoCounter() {}
     163    NoCounter(std::string,std::ostream &) {}
     164    NoCounter(const char *,std::ostream &) {}
     165    NoCounter(std::string) {}
     166    NoCounter(const char *) {}
     167    NoCounter &operator++() { return *this; }
     168    int operator++(int) { return 0; }
     169    NoCounter &operator--() { return *this; }
     170    int operator--(int) { return 0; }
     171    NoCounter &operator+=(int) { return *this;}
     172    NoCounter &operator-=(int) { return *this;}
     173    void reset(int) {}
     174    void reset() {}
     175    operator int() {return 0;}
     176  };
     177
     178  ///@}
     179}
     180
     181#endif
  • new file lemon/time_measure.h

    diff -r e47fb28cda5e -r 5711625e8510 lemon/time_measure.h
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#ifndef LEMON_TIME_MEASURE_H
     20#define LEMON_TIME_MEASURE_H
     21
     22///\ingroup timecount
     23///\file
     24///\brief Tools for measuring cpu usage
     25
     26
     27#ifdef WIN32
     28#include <lemon/bits/mingw32_time.h>
     29#else
     30#include <sys/times.h>
     31#endif
     32
     33#include <sys/time.h>
     34#include <fstream>
     35#include <iostream>
     36#include <unistd.h>
     37
     38namespace lemon {
     39
     40  /// \addtogroup timecount
     41  /// @{
     42
     43  /// A class to store (cpu)time instances.
     44
     45  /// This class stores five time values.
     46  /// - a real time
     47  /// - a user cpu time
     48  /// - a system cpu time
     49  /// - a user cpu time of children
     50  /// - a system cpu time of children
     51  ///
     52  /// TimeStamp's can be added to or substracted from each other and
     53  /// they can be pushed to a stream.
     54  ///
     55  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
     56  /// class is what you want to use instead.
     57  ///
     58  ///\author Alpar Juttner
     59
     60  class TimeStamp
     61  {
     62    struct rtms
     63    {
     64      double tms_utime;
     65      double tms_stime;
     66      double tms_cutime;
     67      double tms_cstime;
     68      rtms() {}
     69      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
     70                     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
     71    };
     72    rtms ts;
     73    double real_time;
     74 
     75    rtms &getTms() {return ts;}
     76    const rtms &getTms() const {return ts;}
     77
     78    void _reset() {
     79      ts.tms_utime = ts.tms_stime = ts.tms_cutime = ts.tms_cstime = 0;
     80      real_time = 0;
     81    }
     82
     83  public:
     84
     85    ///Read the current time values of the process
     86    void stamp()
     87    {
     88      timeval tv;
     89      tms _ts;
     90      times(&_ts);
     91      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
     92      ts=_ts;
     93    }
     94 
     95    /// Constructor initializing with zero
     96    TimeStamp()
     97    { _reset(); }
     98    ///Constructor initializing with the current time values of the process
     99    TimeStamp(void *) { stamp();}
     100 
     101    ///Set every time value to zero
     102    TimeStamp &reset() {_reset();return *this;}
     103
     104    ///\e
     105    TimeStamp &operator+=(const TimeStamp &b)
     106    {
     107      ts.tms_utime+=b.ts.tms_utime;
     108      ts.tms_stime+=b.ts.tms_stime;
     109      ts.tms_cutime+=b.ts.tms_cutime;
     110      ts.tms_cstime+=b.ts.tms_cstime;
     111      real_time+=b.real_time;
     112      return *this;
     113    }
     114    ///\e
     115    TimeStamp operator+(const TimeStamp &b) const
     116    {
     117      TimeStamp t(*this);
     118      return t+=b;
     119    }
     120    ///\e
     121    TimeStamp &operator-=(const TimeStamp &b)
     122    {
     123      ts.tms_utime-=b.ts.tms_utime;
     124      ts.tms_stime-=b.ts.tms_stime;
     125      ts.tms_cutime-=b.ts.tms_cutime;
     126      ts.tms_cstime-=b.ts.tms_cstime;
     127      real_time-=b.real_time;
     128      return *this;
     129    }
     130    ///\e
     131    TimeStamp operator-(const TimeStamp &b) const
     132    {
     133      TimeStamp t(*this);
     134      return t-=b;
     135    }
     136    ///\e
     137    TimeStamp &operator*=(double b)
     138    {
     139      ts.tms_utime*=b;
     140      ts.tms_stime*=b;
     141      ts.tms_cutime*=b;
     142      ts.tms_cstime*=b;
     143      real_time*=b;
     144      return *this;
     145    }
     146    ///\e
     147    TimeStamp operator*(double b) const
     148    {
     149      TimeStamp t(*this);
     150      return t*=b;
     151    }
     152    friend TimeStamp operator*(double b,const TimeStamp &t);
     153    ///\e
     154    TimeStamp &operator/=(double b)
     155    {
     156      ts.tms_utime/=b;
     157      ts.tms_stime/=b;
     158      ts.tms_cutime/=b;
     159      ts.tms_cstime/=b;
     160      real_time/=b;
     161      return *this;
     162    }
     163    ///\e
     164    TimeStamp operator/(double b) const
     165    {
     166      TimeStamp t(*this);
     167      return t/=b;
     168    }
     169    ///The time ellapsed since the last call of stamp()
     170    TimeStamp ellapsed() const
     171    {
     172      TimeStamp t(NULL);
     173      return t-*this;
     174    }
     175 
     176    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
     177 
     178    ///Gives back the user time of the process
     179    double userTime() const
     180    {
     181      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
     182    }
     183    ///Gives back the system time of the process
     184    double systemTime() const
     185    {
     186      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
     187    }
     188    ///Gives back the user time of the process' children
     189    double cUserTime() const
     190    {
     191      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
     192    }
     193    ///Gives back the user time of the process' children
     194    double cSystemTime() const
     195    {
     196      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
     197    }
     198    ///Gives back the real time
     199    double realTime() const {return real_time;}
     200  };
     201
     202  TimeStamp operator*(double b,const TimeStamp &t)
     203  {
     204    return t*b;
     205  }
     206 
     207  ///Prints the time counters
     208
     209  ///Prints the time counters in the following form:
     210  ///
     211  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
     212  ///
     213  /// where the values are the
     214  /// \li \c u: user cpu time,
     215  /// \li \c s: system cpu time,
     216  /// \li \c cu: user cpu time of children,
     217  /// \li \c cs: system cpu time of children,
     218  /// \li \c real: real time.
     219  /// \relates TimeStamp
     220  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
     221  {
     222    long cls = sysconf(_SC_CLK_TCK);
     223    os << "u: " << double(t.getTms().tms_utime)/cls <<
     224      "s, s: " << double(t.getTms().tms_stime)/cls <<
     225      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
     226      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
     227      "s, real: " << t.realTime() << "s";
     228    return os;
     229  }
     230
     231  ///Class for measuring the cpu time and real time usage of the process
     232
     233  ///Class for measuring the cpu time and real time usage of the process.
     234  ///It is quite easy-to-use, here is a short example.
     235  ///\code
     236  /// #include<lemon/time_measure.h>
     237  /// #include<iostream>
     238  ///
     239  /// int main()
     240  /// {
     241  ///
     242  ///   ...
     243  ///
     244  ///   Timer t;
     245  ///   doSomething();
     246  ///   std::cout << t << '\n';
     247  ///   t.restart();
     248  ///   doSomethingElse();
     249  ///   std::cout << t << '\n';
     250  ///
     251  ///   ...
     252  ///
     253  /// }
     254  ///\endcode
     255  ///
     256  ///The \ref Timer can also be \ref stop() "stopped" and
     257  ///\ref start() "started" again, so it is possible to compute collected
     258  ///running times.
     259  ///
     260  ///\warning Depending on the operation system and its actual configuration
     261  ///the time counters have a certain (10ms on a typical Linux system)
     262  ///granularity.
     263  ///Therefore this tool is not appropriate to measure very short times.
     264  ///Also, if you start and stop the timer very frequently, it could lead to
     265  ///distorted results.
     266  ///
     267  ///\note If you want to measure the running time of the execution of a certain
     268  ///function, consider the usage of \ref TimeReport instead.
     269  ///
     270  ///\todo This shouldn't be Unix (Linux) specific.
     271  ///\sa TimeReport
     272  ///
     273  ///\author Alpar Juttner
     274  class Timer
     275  {
     276    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
     277    TimeStamp start_time; //This is the relativ start-time if the timer
     278                          //is _running, the collected _running time otherwise.
     279   
     280    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
     281 
     282  public:
     283    ///Constructor.
     284
     285    ///\param run indicates whether or not the timer starts immediately.
     286    ///
     287    Timer(bool run=true) :_running(run) {_reset();}
     288
     289    ///\name Control the state of the timer
     290    ///Basically a Timer can be either running or stopped,
     291    ///but it provides a bit finer control on the execution.
     292    ///The \ref Timer also counts the number of \ref start()
     293    ///executions, and is stops only after the same amount (or more)
     294    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
     295    ///of recursive functions.
     296    ///
     297
     298    ///@{
     299
     300    ///Reset and stop the time counters
     301
     302    ///This function resets and stops the time counters
     303    ///\sa restart()
     304    void reset()
     305    {
     306      _running=0;
     307      _reset();
     308    }
     309
     310    ///Start the time counters
     311   
     312    ///This function starts the time counters.
     313    ///
     314    ///If the timer is started more than ones, it will remain running
     315    ///until the same amount of \ref stop() is called.
     316    ///\sa stop()
     317    void start()
     318    {
     319      if(_running) _running++;
     320      else {
     321        _running=1;
     322        TimeStamp t;
     323        t.stamp();
     324        start_time=t-start_time;
     325      }
     326    }
     327
     328   
     329    ///Stop the time counters
     330
     331    ///This function stops the time counters. If start() was executed more than
     332    ///once, then the same number of stop() execution is necessary the really
     333    ///stop the timer.
     334    ///
     335    ///\sa halt()
     336    ///\sa start()
     337    ///\sa restart()
     338    ///\sa reset()
     339
     340    void stop()
     341    {
     342      if(_running && !--_running) {
     343        TimeStamp t;
     344        t.stamp();
     345        start_time=t-start_time;
     346      }
     347    }
     348
     349    ///Halt (i.e stop immediately) the time counters
     350
     351    ///This function stops immediately the time counters, i.e. <tt>t.stop()</tt>
     352    ///is a faster
     353    ///equivalent of the following.
     354    ///\code
     355    ///  while(t.running()) t.stop()
     356    ///\endcode
     357    ///
     358    ///
     359    ///\sa stop()
     360    ///\sa restart()
     361    ///\sa reset()
     362
     363    void halt()
     364    {
     365      if(_running) {
     366        _running=0;
     367        TimeStamp t;
     368        t.stamp();
     369        start_time=t-start_time;
     370      }
     371    }
     372
     373    ///Returns the running state of the timer
     374
     375    ///This function returns the number of stop() exections that is
     376    ///necessary to really stop the timer.
     377    ///For example the timer
     378    ///is running if and only if the return value is \c true
     379    ///(i.e. greater than
     380    ///zero).
     381    int running()  { return _running; }
     382   
     383   
     384    ///Restart the time counters
     385
     386    ///This function is a shorthand for
     387    ///a reset() and a start() calls.
     388    ///
     389    void restart()
     390    {
     391      reset();
     392      start();
     393    }
     394   
     395    ///@}
     396
     397    ///\name Query Functions for the ellapsed time
     398
     399    ///@{
     400
     401    ///Gives back the ellapsed user time of the process
     402    double userTime() const
     403    {
     404      return operator TimeStamp().userTime();
     405    }
     406    ///Gives back the ellapsed system time of the process
     407    double systemTime() const
     408    {
     409      return operator TimeStamp().systemTime();
     410    }
     411    ///Gives back the ellapsed user time of the process' children
     412    double cUserTime() const
     413    {
     414      return operator TimeStamp().cUserTime();
     415    }
     416    ///Gives back the ellapsed user time of the process' children
     417    double cSystemTime() const
     418    {
     419      return operator TimeStamp().cSystemTime();
     420    }
     421    ///Gives back the ellapsed real time
     422    double realTime() const
     423    {
     424      return operator TimeStamp().realTime();
     425    }
     426    ///Computes the ellapsed time
     427
     428    ///This conversion computes the ellapsed time, therefore you can print
     429    ///the ellapsed time like this.
     430    ///\code
     431    ///  Timer t;
     432    ///  doSomething();
     433    ///  std::cout << t << '\n';
     434    ///\endcode
     435    operator TimeStamp () const
     436    {
     437      TimeStamp t;
     438      t.stamp();
     439      return _running?t-start_time:start_time;
     440    }
     441
     442
     443    ///@}
     444  };
     445
     446  ///Same as \ref Timer but prints a report on destruction.
     447
     448  ///Same as \ref Timer but prints a report on destruction.
     449  ///This example shows its usage.
     450  ///\code
     451  ///  void myAlg(ListGraph &g,int n)
     452  ///  {
     453  ///    TimeReport tr("Running time of myAlg: ");
     454  ///    ... //Here comes the algorithm
     455  ///  }
     456  ///\endcode
     457  ///
     458  ///\sa Timer
     459  ///\sa NoTimeReport
     460  ///\todo There is no test case for this
     461  class TimeReport : public Timer
     462  {
     463    std::string _title;
     464    std::ostream &_os;
     465  public:
     466    ///\e
     467
     468    ///\param title This text will be printed before the ellapsed time.
     469    ///\param os The stream to print the report to.
     470    ///\param run Sets whether the timer should start immediately.
     471
     472    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
     473      : Timer(run), _title(title), _os(os){}
     474    ///\e Prints the ellapsed time on destruction.
     475    ~TimeReport()
     476    {
     477      _os << _title << *this << std::endl;
     478    }
     479  };
     480     
     481  ///'Do nothing' version of \ref TimeReport
     482
     483  ///\sa TimeReport
     484  ///
     485  class NoTimeReport
     486  {
     487  public:
     488    ///\e
     489    NoTimeReport(std::string,std::ostream &,bool) {}
     490    ///\e
     491    NoTimeReport(std::string,std::ostream &) {}
     492    ///\e
     493    NoTimeReport(std::string) {}
     494    ///\e Do nothing.
     495    ~NoTimeReport() {}
     496
     497    operator TimeStamp () const { return TimeStamp(); }
     498    void reset() {}
     499    void start() {}
     500    void stop() {}
     501    void halt() {}
     502    int running() { return 0; }
     503    void restart() {}
     504    double userTime() const { return 0; }
     505    double systemTime() const { return 0; }
     506    double cUserTime() const { return 0; }
     507    double cSystemTime() const { return 0; }
     508    double realTime() const { return 0; }
     509  };
     510     
     511  ///Tool to measure the running time more exactly.
     512 
     513  ///This function calls \c f several times and returns the average
     514  ///running time. The number of the executions will be choosen in such a way
     515  ///that the full real running time will be roughly between \c min_time
     516  ///and <tt>2*min_time</tt>.
     517  ///\param f the function object to be measured.
     518  ///\param min_time the minimum total running time.
     519  ///\retval num if it is not \c NULL, then the actual
     520  ///        number of execution of \c f will be written into <tt>*num</tt>.
     521  ///\retval full_time if it is not \c NULL, then the actual
     522  ///        total running time will be written into <tt>*full_time</tt>.
     523  ///\return The average running time of \c f.
     524 
     525  template<class F>
     526  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
     527                            TimeStamp *full_time=NULL)
     528  {
     529    TimeStamp full;
     530    unsigned int total=0;
     531    Timer t;
     532    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
     533      for(;total<tn;total++) f();
     534      full=t;
     535    }
     536    if(num) *num=total;
     537    if(full_time) *full_time=full;
     538    return full/total;
     539  }
     540 
     541  /// @} 
     542
     543
     544} //namespace lemon
     545
     546#endif //LEMON_TIME_MEASURE_H
  • test/Makefile.am

    diff -r e47fb28cda5e -r 5711625e8510 test/Makefile.am
    a b  
    99
    1010check_PROGRAMS += \
    1111        test/bfs_test \
     12        test/counter_test \
    1213        test/dfs_test \
    1314        test/digraph_test \
    1415        test/dim_test \
     
    2021        test/path_test \
    2122        test/test_tools_fail \
    2223        test/test_tools_pass \
     24        test/time_measure_test \
    2325        test/unionfind_test
    2426
    2527TESTS += $(check_PROGRAMS)
    2628XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
    2729
    2830test_bfs_test_SOURCES = test/bfs_test.cc
     31test_counter_test_SOURCES = test/counter_test.cc
    2932test_dfs_test_SOURCES = test/dfs_test.cc
    3033test_digraph_test_SOURCES = test/digraph_test.cc
    3134test_dim_test_SOURCES = test/dim_test.cc
     
    3841test_random_test_SOURCES = test/random_test.cc
    3942test_test_tools_fail_SOURCES = test/test_tools_fail.cc
    4043test_test_tools_pass_SOURCES = test/test_tools_pass.cc
     44test_time_measure_test_SOURCES = test/time_measure_test.cc
    4145test_unionfind_test_SOURCES = test/unionfind_test.cc
  • new file test/counter_test.cc

    diff -r e47fb28cda5e -r 5711625e8510 test/counter_test.cc
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#include <lemon/counter.h>
     20
     21///\file \brief Test cases for time_measure.h
     22///
     23///\todo To be extended
     24
     25
     26int fibonacci(int f)
     27{
     28  static lemon::Counter count("Fibonacci steps: ");
     29  count++;
     30  if(f<1) return 0;
     31  else if(f==1) return 1;
     32  else return fibonacci(f-1)+fibonacci(f-2);
     33}
     34
     35int main()
     36{
     37  fibonacci(10);
     38 
     39  { 
     40    typedef lemon::Counter MyCounter;
     41    MyCounter c("Main counter: ");
     42    c++;
     43    c++;
     44    MyCounter::SubCounter d(c,"Subcounter: ");
     45    d++;
     46    d++;
     47    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
     48    e++;
     49    e++;
     50  }
     51 
     52  {
     53    typedef lemon::NoCounter MyCounter;
     54    MyCounter c("Main counter: ");
     55    c++;
     56    c++;
     57    MyCounter::SubCounter d(c,"Subcounter: ");
     58    d++;
     59    d++;
     60    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
     61    e++;
     62    e++;
     63  }
     64
     65  return 0;
     66}
  • new file test/time_measure_test.cc

    diff -r e47fb28cda5e -r 5711625e8510 test/time_measure_test.cc
    - +  
     1/* -*- C++ -*-
     2 *
     3 * This file is a part of LEMON, a generic C++ optimization library
     4 *
     5 * Copyright (C) 2003-2008
     6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8 *
     9 * Permission to use, modify and distribute this software is granted
     10 * provided that this copyright notice appears in all copies. For
     11 * precise terms see the accompanying LICENSE file.
     12 *
     13 * This software is provided "AS IS" with no warranty of any kind,
     14 * express or implied, and with no claim as to its suitability for any
     15 * purpose.
     16 *
     17 */
     18
     19#include <lemon/time_measure.h>
     20
     21///\file \brief Test cases for time_measure.h
     22///
     23///\todo To be extended
     24
     25
     26using namespace lemon;
     27
     28void f()
     29{
     30  double d=0;
     31  for(int i=0;i<1000;i++)
     32    d+=0.1;
     33}
     34
     35void g()
     36{
     37  static Timer T;
     38 
     39  for(int i=0;i<1000;i++)
     40    TimeStamp x(T);
     41}
     42
     43int main()
     44{
     45  Timer T;
     46  unsigned int n;
     47  for(n=0;T.realTime()<1.0;n++) ;
     48  std::cout << T << " (" << n << " time queries)\n";
     49  T.restart();
     50  while(T.realTime()<2.0) ;
     51  std::cout << T << '\n';
     52  TimeStamp full;
     53  TimeStamp t;
     54  t=runningTimeTest(f,1,&n,&full);
     55  std::cout << t << " (" << n << " tests)\n";
     56  std::cout << "Total: " << full << "\n";
     57 
     58  t=runningTimeTest(g,1,&n,&full);
     59  std::cout << t << " (" << n << " tests)\n";
     60  std::cout << "Total: " << full << "\n";
     61 
     62  return 0;
     63}