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