00001 #ifndef Impala_Util_TimeStats_h 00002 #define Impala_Util_TimeStats_h 00003 00004 #include <vector> 00005 #include "Basis/Timer.h" 00006 00007 00016 namespace Impala 00017 { 00018 namespace Util 00019 { 00020 00021 00022 class TimeStats 00023 { 00024 public: 00025 class Group 00026 { 00027 public: 00028 Group(const std::string& name) 00029 :mName(name) 00030 { 00031 Clear(); 00032 } 00033 00034 void AddMeasurement(double time) 00035 { 00036 mMeasurements.push_back(time); 00037 mTotal += time; 00038 } 00039 00040 void Clear() 00041 { 00042 mTotal = 0; 00043 mMeasurements.clear(); 00044 } 00045 00046 std::string mName; 00047 std::vector<double> mMeasurements; 00048 double mTotal; 00049 double mPercentage; // warning: only computed when ComputePercentages of the TimeStats object is called 00050 }; 00051 00052 TimeStats(bool relative=false) 00053 :mClock(1) 00054 { 00055 mIsTiming = false; 00056 mCurrentGroup = 0; 00057 mRelative = relative; 00058 } 00059 00060 void AddGroup(const std::string& name) 00061 { 00062 mGroups.push_back(new Group(name)); 00063 } 00064 00065 void MeasureFirst() 00066 { 00067 StopTime(); 00068 SelectGroup(0); 00069 StartTime(); 00070 } 00071 00072 void MeasureNext() 00073 { 00074 StopTime(); 00075 SelectGroup(mCurrentGroup + 1); 00076 StartTime(); 00077 } 00078 00079 void Print(std::ostream& os) 00080 { 00081 StopTime(); 00082 ComputePercentages(); 00083 os << "timestats - " << mGroups.size() << " groups\n"; 00084 for(int i=0 ; i<mGroups.size() ; i++) 00085 { 00086 Group* g = mGroups[i]; 00087 os << " " << g->mName << ": " << g->mPercentage << "% = " << g->mTotal << " (avrg. " << g->mTotal/g->mMeasurements.size() << ")\n"; 00088 } 00089 os << std::endl; 00090 } 00091 00092 Group* GetCurrentGroup() 00093 { 00094 return mGroups[mCurrentGroup]; 00095 } 00096 00097 const Group* SelectGroup(const std::string& name) 00098 { 00099 if(mIsTiming) 00100 StopTime(); 00101 for(int i=0 ; i<mGroups.size() ; i++) 00102 if(mGroups[i]->mName == name) 00103 return SelectGroup(i); 00104 } 00105 00106 const Group* SelectGroup(int number) 00107 { 00108 if(mIsTiming) 00109 StopTime(); 00110 if(number < mGroups.size()) 00111 mCurrentGroup = number; 00112 return GetCurrentGroup(); 00113 } 00114 00115 void StartTime() 00116 { 00117 mIsTiming = true; 00118 mClock.Start(); 00119 } 00120 00121 void StopTime() 00122 { 00123 if(mIsTiming) 00124 GetCurrentGroup()->AddMeasurement(mClock.Stop()); 00125 mIsTiming = false; 00126 } 00127 00128 void Reset() 00129 { 00130 if(mIsTiming) 00131 StopTime(); 00132 for(int i=0 ; i<mGroups.size() ; i++) 00133 mGroups[i]->Clear(); 00134 } 00135 00136 void ComputePercentages() 00137 { 00138 double total = 0; 00139 int i; 00140 if(mRelative) 00141 total = mGroups[0]->mTotal; 00142 else 00143 for(i=0 ; i<mGroups.size() ; i++) 00144 total += mGroups[i]->mTotal; 00145 for(i=0 ; i<mGroups.size() ; i++) 00146 mGroups[i]->mPercentage = 100. * mGroups[i]->mTotal / total; 00147 } 00148 00149 protected: 00150 Timer mClock; 00151 std::vector<Group*> mGroups; 00152 int mCurrentGroup; 00153 bool mIsTiming; 00154 bool mRelative; 00155 00156 friend std::ostream& operator<< (std::ostream& os, TimeStats& stats); 00157 }; 00158 00159 std::ostream& operator<< (std::ostream& os, TimeStats& stats) 00160 { 00161 stats.Print(os); 00162 return os; 00163 } 00164 00165 }//namespace Util 00166 }//namespace Impala 00167 00168 #endif 00169