Add a time-profiler with statistics
authorRobin Gareus <robin@gareus.org>
Thu, 17 May 2018 20:00:27 +0000 (22:00 +0200)
committerRobin Gareus <robin@gareus.org>
Thu, 17 May 2018 20:15:07 +0000 (22:15 +0200)
libs/pbd/pbd/timing.h

index 9c93165b3a4a026a054d8ec341bd73e686ce16ef..470751f972e6d295c89df6feb3bed281fef191a6 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <stdint.h>
 
+#include <cmath>
+#include <limits>
 #include <string>
 #include <vector>
 
@@ -110,6 +112,84 @@ private:
 
 };
 
+class LIBPBD_API TimingStats : public Timing
+{
+public:
+       TimingStats ()
+       {
+               /* override implicit Timing::start () */
+               reset ();
+       }
+
+       void update ()
+       {
+               Timing::update ();
+               calc ();
+       }
+
+       void reset ()
+       {
+               Timing::reset ();
+               _min = std::numeric_limits<uint64_t>::max();
+               _max = 0;
+               _cnt = 0;
+               _avg = 0.;
+               _vm  = 0.;
+               _vs  = 0.;
+       }
+
+       bool valid () const {
+               return Timing::valid () && _cnt > 1;
+       }
+
+       bool get_stats (uint64_t& min,
+                       uint64_t& max,
+                       double& avg,
+                       double& dev) const
+       {
+               if (_cnt < 2) {
+                       return false;
+               }
+               min = _min;
+               max = _max;
+               avg = _avg / (double)_cnt;
+               dev = sqrt (_vs / (_cnt - 1.0));
+               return true;
+       }
+
+private:
+       void calc ()
+       {
+               const uint64_t diff = elapsed ();
+
+               _avg += diff;
+
+               if (diff > _max) {
+                       _max = diff;
+               }
+               if (diff < _min) {
+                       _min = diff;
+               }
+
+               if (_cnt == 0) {
+                       _vm = diff;
+               } else {
+                       const double ela = diff;
+                       const double var_m1 = _vm;
+                       _vm = _vm + (ela - _vm) / (1.0 + _cnt);
+                       _vs = _vs + (ela - _vm) * (ela - var_m1);
+               }
+               ++_cnt;
+       }
+
+       uint64_t _cnt;
+       uint64_t _min;
+       uint64_t _max;
+       double   _avg;
+       double   _vm;
+       double   _vs;
+};
+
 class LIBPBD_API TimingData
 {
 public: