c++ - Quick and dirty way to profile your code -


what method use when want performance data specific code paths?

this method has several limitations, still find useful. i'll list limitations (i know of) front , let whoever wants use @ own risk.

  1. the original version posted over-reported time spent in recursive calls (as pointed out in comments answer).
  2. it's not thread safe, wasn't thread safe before added code ignore recursion , it's less thread safe now.
  3. although it's efficient if it's called many times (millions), have measurable effect on outcome scopes measure take longer don't.

i use class when problem @ hand doesn't justify profiling code or data profiler want verify. sums time spent in specific block , @ end of program outputs debug stream (viewable dbgview), including how many times code executed (and average time spent of course)).

#pragma once #include <tchar.h> #include <windows.h> #include <sstream> #include <boost/noncopyable.hpp>  namespace scope_timer {     class time_collector : boost::noncopyable {         __int64 total;         large_integer start;         size_t times;         const tchar* name;          double cpu_frequency()         { // cache cpu frequency, doesn't change.             static double ret = 0; // store double devision later on floating point , not truncating             if (ret == 0) {                 large_integer freq;                 queryperformancefrequency(&freq);                 ret = static_cast<double>(freq.quadpart);             }             return ret;         }         bool in_use;      public:         time_collector(const tchar* n)             : times(0)             , name(n)             , total(0)             , start(large_integer())             , in_use(false)         {         }          ~time_collector()         {             std::basic_ostringstream<tchar> msg;             msg << _t("scope_timer> ") <<  name << _t(" called: ");              double seconds = total / cpu_frequency();             double average = seconds / times;              msg << times << _t(" times total time: ") << seconds << _t(" seconds  ")                 << _t(" (avg ") << average <<_t(")\n");             outputdebugstring(msg.str().c_str());         }          void add_time(__int64 ticks)         {             total += ticks;             ++times;             in_use = false;         }          bool aquire()         {             if (in_use)                 return false;             in_use = true;             return true;         }     };      class one_time : boost::noncopyable {         large_integer start;         time_collector* collector;     public:         one_time(time_collector& tc)         {             if (tc.aquire()) {                 collector = &tc;                 queryperformancecounter(&start);             }             else                 collector = 0;         }          ~one_time()         {             if (collector) {                 large_integer end;                 queryperformancecounter(&end);                 collector->add_time(end.quadpart - start.quadpart);             }         }     }; }  // usage time_this_scope(xx); xx c variable name (can begin number) #define time_this_scope(name) \     static scope_timer::time_collector st_time_collector_##name(_t(#name)); \     scope_timer::one_time st_one_time_##name(st_time_collector_##name) 

Comments

Popular posts from this blog

windows - Why does Vista not allow creation of shortcuts to "Programs" on a NonAdmin account? Not supposed to install apps from NonAdmin account? -

c++ - How do I get a multi line tooltip in MFC -

unit testing - How to mock PreferenceManager in Android? -