timer.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /****************************************************************************************************/ 00008 00009 #ifndef ADOBE_TIMER_HPP 00010 #define ADOBE_TIMER_HPP 00011 00012 /****************************************************************************************************/ 00013 00090 /****************************************************************************************************/ 00091 00092 #include <adobe/config.hpp> 00093 00094 #include <adobe/algorithm/minmax.hpp> 00095 #include <adobe/algorithm/sort.hpp> 00096 #include <adobe/numeric.hpp> 00097 00098 #include <boost/operators.hpp> 00099 00100 #if ADOBE_PLATFORM_WIN 00101 #ifndef WINDOWS_LEAN_AND_MEAN 00102 #define WINDOWS_LEAN_AND_MEAN 00103 #define ADOBE_UNDEFINE_WINDOWS_LEAN_AND_MEAN 1 00104 #endif 00105 #include <windows.h> 00106 #if ADOBE_UNDEFINE_WINDOWS_LEAN_AND_MEAN 00107 #undef WINDOWS_LEAN_AND_MEAN 00108 #undef ADOBE_UNDEFINE_WINDOWS_LEAN_AND_MEAN 00109 #endif 00110 #elif defined(BOOST_HAS_THREADS) 00111 #include <boost/thread/xtime.hpp> 00112 #elif defined(BOOST_HAS_GETTIMEOFDAY) 00113 #include <sys/time.h> 00114 #endif 00115 00116 #include <iostream> 00117 #include <vector> 00118 #include <cassert> 00119 00120 /****************************************************************************************************/ 00121 00122 namespace adobe { 00123 00124 /****************************************************************************************************/ 00125 00126 class timer_t : boost::totally_ordered<timer_t> 00127 { 00128 #if ADOBE_PLATFORM_WIN 00129 typedef LARGE_INTEGER value_type; 00130 #elif defined(BOOST_HAS_THREADS) 00131 typedef boost::xtime value_type; 00132 #elif defined(BOOST_HAS_GETTIMEOFDAY) 00133 typedef timeval value_type; 00134 #endif 00135 00136 typedef std::vector<double> accumulator_type; 00137 00138 public: 00139 typedef accumulator_type::size_type size_type; 00140 00141 #ifndef ADOBE_NO_DOCUMENTATION 00142 00143 timer_t() 00144 { 00145 #if ADOBE_PLATFORM_WIN 00146 (void)::QueryPerformanceFrequency(&frequency_m); 00147 #endif 00148 00149 reset(); 00150 } 00151 00152 timer_t(const timer_t& rhs) : 00153 epoch_m(rhs.epoch_m), 00154 split_m(rhs.split_m), 00155 time_set_m(rhs.time_set_m) 00156 #if ADOBE_PLATFORM_WIN 00157 , frequency_m(rhs.frequency_m) 00158 #endif 00159 { } 00160 00161 timer_t& operator = (const timer_t& rhs) 00162 { 00163 epoch_m = rhs.epoch_m; 00164 split_m = rhs.split_m; 00165 time_set_m = rhs.time_set_m; 00166 00167 #if ADOBE_PLATFORM_WIN 00168 frequency_m = rhs.frequency_m; 00169 #endif 00170 00171 return *this; 00172 } 00173 00174 #endif 00175 00180 inline void reset() 00181 { 00182 #if ADOBE_PLATFORM_WIN 00183 (void)::QueryPerformanceCounter(&epoch_m); 00184 #elif defined(BOOST_HAS_THREADS) 00185 boost::xtime_get(&epoch_m, boost::TIME_UTC); 00186 #elif defined(BOOST_HAS_GETTIMEOFDAY) 00187 gettimeofday(&epoch_m, static_cast<struct timezone*>(0)); 00188 #endif 00189 } 00190 00195 inline void reset_accumulator() 00196 { time_set_m.clear(); } 00197 00203 inline double split() 00204 { 00205 #if ADOBE_PLATFORM_WIN 00206 (void)::QueryPerformanceCounter(&split_m); 00207 return (split_m.QuadPart - epoch_m.QuadPart) / static_cast<double>(frequency_m.QuadPart) * double(1e3); 00208 #elif defined(BOOST_HAS_THREADS) 00209 boost::xtime_get(&split_m, boost::TIME_UTC); 00210 return ((split_m.sec - epoch_m.sec) * double(1e3) + (split_m.nsec - epoch_m.nsec) / double(1e6)); 00211 #elif defined(BOOST_HAS_GETTIMEOFDAY) 00212 gettimeofday(&split_m, static_cast<struct timezone*>(0)); 00213 return ((split_m.tv_sec - epoch_m.tv_sec) * double(1e3) + (split_m.tv_usec - epoch_m.tv_usec) / double(1e3)); 00214 #else 00215 return -1; 00216 #endif 00217 00218 } 00219 00224 inline void accrue() 00225 { time_set_m.push_back(split()); reset(); } 00226 00232 inline double accrued_min() const 00233 { return *adobe::min_element(time_set_m); } 00234 00240 inline double accrued_max() const 00241 { return *adobe::max_element(time_set_m); } 00242 00248 inline double accrued_average() const 00249 { return empty() ? 0 : accrued_total() / size(); } 00250 00256 inline double accrued_median() const 00257 { 00258 if (empty()) 00259 return 0; 00260 00261 adobe::sort(time_set_m); 00262 00263 return (size() % 2 == 1) ? 00264 time_set_m[time_set_m.size() / 2] : 00265 (time_set_m[time_set_m.size() / 2] + 00266 time_set_m[time_set_m.size() / 2 - 1]) / 2; 00267 } 00268 00274 inline double accrued_total() const 00275 { return adobe::accumulate(time_set_m, double(0)); } 00276 00282 inline size_type size() const 00283 { return time_set_m.size(); } 00284 00290 inline bool empty() const 00291 { return time_set_m.empty(); } 00292 00300 inline void report(const char* decoration, std::ostream& s = std::cout) 00301 { 00302 double time(split()); 00303 00304 s << decoration << " took " << time << " milliseconds (" << time / 1e3 << " sec)" << std::endl; 00305 00306 reset(); 00307 } 00308 00309 private: 00310 #ifndef ADOBE_NO_DOCUMENTATION 00311 friend bool operator == (const timer_t& x, const timer_t& y); 00312 friend bool operator < (const timer_t& x, const timer_t& y); 00313 #endif 00314 00315 value_type epoch_m; 00316 value_type split_m; 00317 mutable accumulator_type time_set_m; 00318 #if ADOBE_PLATFORM_WIN 00319 value_type frequency_m; 00320 #endif 00321 }; 00322 00323 /****************************************************************************************************/ 00324 00325 #ifndef ADOBE_NO_DOCUMENTATION 00326 00327 inline bool operator == (const timer_t& /*x*/, const timer_t& /*y*/) 00328 { return true; } 00329 00330 /****************************************************************************************************/ 00331 00332 inline bool operator < (const timer_t& /*x*/, const timer_t& /*y*/) 00333 { return false; } 00334 00335 #endif 00336 00337 /****************************************************************************************************/ 00338 00339 } // namespace adobe 00340 00341 /****************************************************************************************************/ 00342 00343 #endif 00344 00345 /****************************************************************************************************/ |