src/lemon/time_measure.h
author deba
Fri, 04 Mar 2005 17:16:01 +0000
changeset 1192 aa4483befa56
parent 1069 7b81a36809c6
child 1359 1581f961cfaa
permissions -rw-r--r--
Adding GraphEdgeSet and GraphNodeSet classes to graph_utils.h.
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/lemon/time_measure.h - Part of LEMON, a generic C++ optimization library
alpar@906
     3
 *
alpar@1164
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@906
    16
alpar@921
    17
#ifndef LEMON_TIME_MEASURE_H
alpar@921
    18
#define LEMON_TIME_MEASURE_H
alpar@428
    19
klao@491
    20
///\ingroup misc
alpar@428
    21
///\file
alpar@428
    22
///\brief Tools for measuring cpu usage
alpar@428
    23
alpar@428
    24
#include <sys/time.h>
alpar@428
    25
#include <sys/times.h>
alpar@428
    26
#include <fstream>
alpar@428
    27
#include <iostream>
alpar@428
    28
#include <unistd.h>
alpar@428
    29
alpar@921
    30
namespace lemon {
alpar@428
    31
alpar@428
    32
  /// \addtogroup misc
alpar@428
    33
  /// @{
alpar@428
    34
alpar@428
    35
  /// A class to store (cpu)time instances.
alpar@428
    36
alpar@428
    37
  /// This class stores five time values.
alpar@428
    38
  /// - a real time
alpar@428
    39
  /// - a user cpu time
alpar@428
    40
  /// - a system cpu time
alpar@428
    41
  /// - a user cpu time of children
alpar@428
    42
  /// - a system cpu time of children
alpar@428
    43
  ///
alpar@428
    44
  /// TimeStamp's can be added to or substracted from each other and
alpar@428
    45
  /// they can be pushed to a stream.
alpar@458
    46
  ///
alpar@458
    47
  /// In most cases, perhaps \ref Timer class is what you want to use instead.
alpar@458
    48
  ///
alpar@458
    49
  ///\author Alpar Juttner
alpar@428
    50
alpar@428
    51
  class TimeStamp
alpar@428
    52
  {
alpar@428
    53
    tms ts;
alpar@428
    54
    double real_time;
alpar@428
    55
  
alpar@428
    56
  public:
alpar@428
    57
alpar@428
    58
    tms &getTms() {return ts;}
alpar@428
    59
    const tms &getTms() const {return ts;}
alpar@428
    60
    ///Read the current time values of the process
alpar@428
    61
    void stamp()
alpar@428
    62
    {
alpar@428
    63
      timeval tv;
alpar@428
    64
      times(&ts);
alpar@428
    65
      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
alpar@428
    66
    }
alpar@428
    67
  
alpar@428
    68
    /// Constructor initializing with zero
alpar@428
    69
    TimeStamp()
alpar@428
    70
    { ts.tms_utime=ts.tms_stime=ts.tms_cutime=ts.tms_cstime=0; real_time=0;}
alpar@428
    71
    ///Constructor initializing with the current time values of the process
alpar@428
    72
    TimeStamp(void *) { stamp();}
alpar@428
    73
  
alpar@1005
    74
    ///\e
alpar@428
    75
    TimeStamp &operator+=(const TimeStamp &b)
alpar@428
    76
    {
alpar@428
    77
      ts.tms_utime+=b.ts.tms_utime;
alpar@428
    78
      ts.tms_stime+=b.ts.tms_stime;
alpar@428
    79
      ts.tms_cutime+=b.ts.tms_cutime;
alpar@428
    80
      ts.tms_cstime+=b.ts.tms_cstime;
alpar@428
    81
      real_time+=b.real_time;
alpar@428
    82
      return *this;
alpar@428
    83
    }
alpar@1005
    84
    ///\e
alpar@428
    85
    TimeStamp operator+(const TimeStamp &b) const
alpar@428
    86
    {
alpar@428
    87
      TimeStamp t(*this);
alpar@428
    88
      return t+=b;
alpar@428
    89
    }
alpar@1005
    90
    ///\e
alpar@428
    91
    TimeStamp &operator-=(const TimeStamp &b)
alpar@428
    92
    {
alpar@428
    93
      ts.tms_utime-=b.ts.tms_utime;
alpar@428
    94
      ts.tms_stime-=b.ts.tms_stime;
alpar@428
    95
      ts.tms_cutime-=b.ts.tms_cutime;
alpar@428
    96
      ts.tms_cstime-=b.ts.tms_cstime;
alpar@428
    97
      real_time-=b.real_time;
alpar@428
    98
      return *this;
alpar@428
    99
    }
alpar@1005
   100
    ///\e
alpar@428
   101
    TimeStamp operator-(const TimeStamp &b) const
alpar@428
   102
    {
alpar@428
   103
      TimeStamp t(*this);
alpar@428
   104
      return t-=b;
alpar@428
   105
    }
alpar@428
   106
    ///The time ellapsed since the last call of stamp()
alpar@428
   107
    TimeStamp ellapsed() const
alpar@428
   108
    {
alpar@428
   109
      TimeStamp t(NULL);
alpar@428
   110
      return t-*this;
alpar@428
   111
    }
alpar@428
   112
  
alpar@428
   113
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
alpar@428
   114
  
alpar@428
   115
    ///Gives back the user time of the process
alpar@428
   116
    double getUserTime() const
alpar@428
   117
    {
alpar@428
   118
      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
alpar@428
   119
    }
alpar@428
   120
    ///Gives back the system time of the process
alpar@428
   121
    double getSystemTime() const
alpar@428
   122
    {
alpar@428
   123
      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
alpar@428
   124
    }
alpar@428
   125
    ///Gives back the user time of the process' children
alpar@428
   126
    double getCUserTime() const
alpar@428
   127
    {
alpar@428
   128
      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
alpar@428
   129
    }
alpar@428
   130
    ///Gives back the user time of the process' children
alpar@428
   131
    double getCSystemTime() const
alpar@428
   132
    {
alpar@428
   133
      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
alpar@428
   134
    }
alpar@428
   135
    ///Gives back the real time of the process
alpar@428
   136
    double getRealTime() const {return real_time;}
alpar@428
   137
  };
alpar@428
   138
alpar@428
   139
  ///Class measuring the cpu time and real time usage of the process
alpar@458
   140
alpar@458
   141
  ///Class measuring the cpu time and real time usage of the process.
alpar@458
   142
  ///It is quite easy-to-use, here is a short example.
alpar@458
   143
  ///\code
alpar@921
   144
  ///#include<lemon/time_measure.h>
alpar@696
   145
  ///#include<iostream>
alpar@814
   146
  ///
alpar@458
   147
  ///int main()
alpar@458
   148
  ///{
alpar@458
   149
  ///
alpar@458
   150
  ///  ...
alpar@458
   151
  ///
alpar@696
   152
  ///  Timer T;
alpar@458
   153
  ///  doSomething();
alpar@696
   154
  ///  std::cout << T << '\n';
alpar@458
   155
  ///  T.reset();
alpar@458
   156
  ///  doSomethingElse();
alpar@696
   157
  ///  std::cout << T << '\n';
alpar@458
   158
  ///
alpar@458
   159
  ///  ...
alpar@458
   160
  ///
alpar@458
   161
  ///}
alpar@458
   162
  ///\endcode
alpar@458
   163
  ///
alpar@458
   164
  ///\todo This shouldn't be Unix (Linux) specific.
alpar@458
   165
  ///
alpar@458
   166
  ///\author Alpar Juttner
alpar@428
   167
  class Timer
alpar@428
   168
  {
alpar@428
   169
    TimeStamp start_time;
alpar@428
   170
alpar@428
   171
    void _reset() {start_time.stamp();}
alpar@428
   172
  
alpar@428
   173
  public: 
alpar@428
   174
    ///Constructor. It starts with zero time counters
alpar@428
   175
    Timer() {_reset();}
alpar@428
   176
alpar@428
   177
    ///Computes the ellapsed time
alpar@428
   178
alpar@428
   179
    ///This conversion computes the ellapsed time
alpar@428
   180
    ///since the construction of \c t or since
alpar@428
   181
    ///the last \c t.reset().
alpar@1005
   182
    operator TimeStamp () const
alpar@428
   183
    {
alpar@428
   184
      TimeStamp t;
alpar@428
   185
      t.stamp();
alpar@428
   186
      return t-start_time;
alpar@428
   187
    }
alpar@428
   188
alpar@428
   189
    ///Resets the time counters
alpar@1069
   190
alpar@1069
   191
    ///Resets the time counters
alpar@1069
   192
    ///
alpar@1069
   193
    void reset()
alpar@428
   194
    {
alpar@428
   195
      _reset();
alpar@428
   196
    }
alpar@1005
   197
alpar@1005
   198
alpar@1005
   199
    ///Gives back the ellapsed user time of the process
alpar@1005
   200
    double getUserTime() const
alpar@1005
   201
    {
alpar@1005
   202
      return operator TimeStamp().getUserTime();
alpar@1005
   203
    }
alpar@1005
   204
    ///Gives back the ellapsed system time of the process
alpar@1005
   205
    double getSystemTime() const
alpar@1005
   206
    {
alpar@1005
   207
      return operator TimeStamp().getSystemTime();
alpar@1005
   208
    }
alpar@1005
   209
    ///Gives back the ellapsed user time of the process' children
alpar@1005
   210
    double getCUserTime() const
alpar@1005
   211
    {
alpar@1005
   212
      return operator TimeStamp().getCUserTime();
alpar@1005
   213
    }
alpar@1005
   214
    ///Gives back the ellapsed user time of the process' children
alpar@1005
   215
    double getCSystemTime() const
alpar@1005
   216
    {
alpar@1005
   217
      return operator TimeStamp().getCSystemTime();
alpar@1005
   218
    }
alpar@1005
   219
    ///Gives back the ellapsed real time of the process
alpar@1005
   220
    double getRealTime() const
alpar@1005
   221
    {
alpar@1005
   222
      return operator TimeStamp().getRealTime();
alpar@1005
   223
    }
alpar@1005
   224
alpar@428
   225
  };
alpar@428
   226
alpar@428
   227
  ///Prints the time counters
alpar@428
   228
klao@492
   229
  ///Prints the time counters in the following form:
alpar@428
   230
  ///
alpar@440
   231
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
alpar@428
   232
  ///
alpar@428
   233
  /// where the values are the
alpar@440
   234
  /// \li \c u: user cpu time,
alpar@440
   235
  /// \li \c s: system cpu time,
alpar@440
   236
  /// \li \c cu: user cpu time of children,
alpar@440
   237
  /// \li \c cs: system cpu time of children,
alpar@440
   238
  /// \li \c real: real time.
alpar@814
   239
  /// \relates TimeStamp
alpar@428
   240
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
alpar@428
   241
  {
alpar@428
   242
    long cls = sysconf(_SC_CLK_TCK);
alpar@428
   243
    os << "u: " << double(t.getTms().tms_utime)/cls <<
alpar@428
   244
      "s, s: " << double(t.getTms().tms_stime)/cls <<
alpar@428
   245
      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
alpar@428
   246
      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
alpar@428
   247
      "s, real: " << t.getRealTime() << "s";
alpar@428
   248
    return os;
alpar@428
   249
  }
alpar@428
   250
alpar@428
   251
  /// @}  
alpar@428
   252
alpar@921
   253
} //namespace lemon
alpar@428
   254
alpar@921
   255
#endif //LEMON_TIME_MEASURE_H