Timer.h

Go to the documentation of this file.
00001 
00028 #ifndef Timer_h
00029 #define Timer_h
00030 //----------------------------------------------------------------------
00031 #include <iostream>
00032 #include <stdio.h>
00033 #include <time.h>
00034 
00035 #ifndef WIN32
00036 #  include <sys/time.h>
00037 #  include <sys/times.h>
00038 #  include <unistd.h>
00039 #endif
00040 
00041 using namespace std;
00042 //----------------------------------------------------------------------
00044 class Timer {
00045   private:
00046     static long    indent;  
00047     //for summary stats
00048     static double  best;
00049     static double  worst;
00050     static double  total;
00051     static long    count;
00052 
00053     double  mStart;
00054     #ifdef WIN32
00055         //long            tc_start;
00056         FILETIME  mKernelTime, mUserTime;
00057     #else
00058         //struct timeval  tv_start;
00059         struct tms  mStartUsage;
00060     #endif
00061     char*  msg;
00062     bool   summary;
00063 
00064   public:
00065     inline Timer ( const bool summary=false ) {
00066         Timer( (char*)NULL, summary );
00067     }
00068     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00069     inline Timer ( char* m, const bool summary=false ) {
00070         //init our "timer" to determine how long will this take.
00071         ++Timer::indent;
00072         this->msg = m;
00073         this->summary = summary;
00074         reset();
00075     }
00076     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00078     inline void reset ( void ) {
00079         #ifdef WIN32
00080             mStart = GetTickCount();
00081 
00082             FILETIME  creationTime, exitTime;
00083             GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime,
00084                 &mKernelTime, &mUserTime );
00085         #else
00086             struct timeval   tv_start;
00087             struct timezone  tz_start;
00088             gettimeofday( &tv_start, &tz_start );
00089             mStart = tv_start.tv_sec + (tv_start.tv_usec / 1E6);
00090 
00091             times( &mStartUsage );
00092         #endif
00093     }
00094     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00096     inline double getElapsedTime ( void ) {
00097         #ifdef WIN32
00098             long  tc_end = GetTickCount();
00099             return  (tc_end-mStart) / 1E3;
00100         #else
00101             struct timeval  tv_end;
00102             struct timezone tz_end;
00103             gettimeofday(&tv_end, &tz_end);
00104             double d_end   = tv_end.tv_sec + (tv_end.tv_usec / 1E6);
00105             return (d_end-mStart);
00106         #endif
00107     }
00108     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00111     inline void report ( void ) {
00112         for (int i=0; i<Timer::indent; i++)    cout << "  ";
00113         if (this->msg != NULL) {
00114             cout << this->msg << " ";
00115         }
00116         cout << "elapsed time=" << getElapsedTime() << "s,";
00117         cout << " CPU time=" << getCPUTime() << "s";
00118 
00119         if (this->summary) {
00120             cout << ", best=" << Timer::best << ", worst=" << Timer::worst
00121                  << ", average=" << (Timer::total/Timer::count);
00122         }
00123 
00124         cout << endl;
00125     }
00126     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00128     inline double getCPUTime ( void ) {
00129       #ifdef  WIN32
00130         FILETIME  creationTime, exitTime, kernelTime, userTime;
00131         GetProcessTimes( GetCurrentProcess(), &creationTime, &exitTime,
00132             &kernelTime, &userTime );
00133         //as recommended by bill:
00134         // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp
00135         ULARGE_INTEGER  u2;
00136         memcpy( &u2, &userTime, sizeof(userTime) );
00137         __int64*  i2 = (__int64*)&u2;
00138         ULARGE_INTEGER  u1;
00139         memcpy( &u1, &mUserTime, sizeof(mUserTime) );
00140         __int64*  i1 = (__int64*)&u1;
00141         __int64   i3 = *i2 - *i1;
00142         //from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/filetime_str.asp
00143         // The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
00144         const double  userCPUTime = i3 * 100 / 1E9;
00145 
00146         //determine kernel cpu time
00147         memcpy( &u2, &kernelTime, sizeof(kernelTime) );
00148         i2 = (__int64*)&u2;
00149         memcpy( &u1, &mKernelTime, sizeof(mKernelTime) );
00150         i1 = (__int64*)&u1;
00151         i3 = *i2 - *i1;
00152         const double  kernelCPUTime = i3 * 100 / 1E9;
00153 
00154         return userCPUTime + kernelCPUTime;
00155       #else
00156         struct tms  usageAfter;
00157         times( &usageAfter );
00158         double  cpuTime = ((double)usageAfter.tms_utime - mStartUsage.tms_utime)
00159                                  / sysconf(_SC_CLK_TCK);
00160         cpuTime += ((double)usageAfter.tms_stime - mStartUsage.tms_stime)
00161                                  / sysconf(_SC_CLK_TCK);
00162         return cpuTime;
00163       #endif
00164     }
00165     // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00166     inline ~Timer ( ) {
00167         const double t = getElapsedTime();
00168         if (this->summary) {
00169             Timer::total += t;
00170             ++Timer::count;
00171             if (t>Timer::worst)  Timer::worst=t;
00172             if (t<Timer::best)   Timer::best =t;
00173         }
00174         report();
00175         --Timer::indent;
00176     }
00177 };
00178 
00179 long   Timer::indent = 0;
00180 double Timer::best   = FLT_MAX;
00181 double Timer::worst  = 0.0;
00182 double Timer::total  = 0.0;
00183 long   Timer::count  = 0;
00184 
00185 #endif
00186 //----------------------------------------------------------------------

Generated on Thu Jan 12 10:28:43 2006 by  doxygen 1.4.5