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
00048 static double best;
00049 static double worst;
00050 static double total;
00051 static long count;
00052
00053 double mStart;
00054 #ifdef WIN32
00055
00056 FILETIME mKernelTime, mUserTime;
00057 #else
00058
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
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
00134
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
00143
00144 const double userCPUTime = i3 * 100 / 1E9;
00145
00146
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