]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/profiler.cpp
Patch built-in Lua to fix miscompile on Android (#12347)
[dragonfireclient.git] / src / profiler.cpp
index 8e997442c9391392dfa08730deac3ffca6176f50..d05b7abfe36cafb0f5425d49c552969f7e7dec90 100644 (file)
@@ -18,15 +18,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "profiler.h"
+#include "porting.h"
 
 static Profiler main_profiler;
 Profiler *g_profiler = &main_profiler;
 ScopeProfiler::ScopeProfiler(
-               Profiler *profiler, const std::string &name, ScopeProfilerType type)
-    : m_profiler(profiler), m_name(name), m_timer(NULL), m_type(type)
+               Profiler *profiler, const std::string &name, ScopeProfilerType type) :
+               m_profiler(profiler),
+               m_name(name), m_type(type)
 {
+       m_name.append(" [ms]");
        if (m_profiler)
-               m_timer = new TimeTaker(m_name);
+               m_timer = new TimeTaker(m_name, nullptr, PRECISION_MILLI);
 }
 
 ScopeProfiler::~ScopeProfiler()
@@ -35,7 +38,7 @@ ScopeProfiler::~ScopeProfiler()
                return;
 
        float duration_ms = m_timer->stop(true);
-       float duration = duration_ms / 1000.0;
+       float duration = duration_ms;
        if (m_profiler) {
                switch (m_type) {
                case SPT_ADD:
@@ -51,3 +54,129 @@ ScopeProfiler::~ScopeProfiler()
        }
        delete m_timer;
 }
+
+Profiler::Profiler()
+{
+       m_start_time = porting::getTimeMs();
+}
+
+void Profiler::add(const std::string &name, float value)
+{
+       MutexAutoLock lock(m_mutex);
+       {
+               /* No average shall have been used; mark add used as -2 */
+               std::map<std::string, int>::iterator n = m_avgcounts.find(name);
+               if (n == m_avgcounts.end()) {
+                       m_avgcounts[name] = -2;
+               } else {
+                       if (n->second == -1)
+                               n->second = -2;
+                       assert(n->second == -2);
+               }
+       }
+       {
+               std::map<std::string, float>::iterator n = m_data.find(name);
+               if (n == m_data.end())
+                       m_data[name] = value;
+               else
+                       n->second += value;
+       }
+}
+
+void Profiler::avg(const std::string &name, float value)
+{
+       MutexAutoLock lock(m_mutex);
+       int &count = m_avgcounts[name];
+
+       assert(count != -2);
+       count = MYMAX(count, 0) + 1;
+       m_data[name] += value;
+}
+
+void Profiler::clear()
+{
+       MutexAutoLock lock(m_mutex);
+       for (auto &it : m_data) {
+               it.second = 0;
+       }
+       m_avgcounts.clear();
+       m_start_time = porting::getTimeMs();
+}
+
+float Profiler::getValue(const std::string &name) const
+{
+       auto numerator = m_data.find(name);
+       if (numerator == m_data.end())
+               return 0.f;
+
+       auto denominator = m_avgcounts.find(name);
+       if (denominator != m_avgcounts.end()) {
+               if (denominator->second >= 1)
+                       return numerator->second / denominator->second;
+       }
+
+       return numerator->second;
+}
+
+int Profiler::getAvgCount(const std::string &name) const
+{
+       auto n = m_avgcounts.find(name);
+
+       if (n != m_avgcounts.end() && n->second >= 1)
+               return n->second;
+
+       return 1;
+}
+
+u64 Profiler::getElapsedMs() const
+{
+       return porting::getTimeMs() - m_start_time;
+}
+
+int Profiler::print(std::ostream &o, u32 page, u32 pagecount)
+{
+       GraphValues values;
+       getPage(values, page, pagecount);
+       char num_buf[50];
+
+       for (const auto &i : values) {
+               o << "  " << i.first << " ";
+               if (i.second == 0) {
+                       o << std::endl;
+                       continue;
+               }
+
+               s32 space = 44 - i.first.size();
+               for (s32 j = 0; j < space; j++) {
+                       if ((j & 1) && j < space - 1)
+                               o << ".";
+                       else
+                               o << " ";
+               }
+               porting::mt_snprintf(num_buf, sizeof(num_buf), "% 4ix % 3g",
+                               getAvgCount(i.first), i.second);
+               o << num_buf << std::endl;
+       }
+       return values.size();
+}
+
+void Profiler::getPage(GraphValues &o, u32 page, u32 pagecount)
+{
+       MutexAutoLock lock(m_mutex);
+
+       u32 minindex, maxindex;
+       paging(m_data.size(), page, pagecount, minindex, maxindex);
+
+       for (const auto &i : m_data) {
+               if (maxindex == 0)
+                       break;
+               maxindex--;
+
+               if (minindex != 0) {
+                       minindex--;
+                       continue;
+               }
+
+               o[i.first] = i.second / getAvgCount(i.first);
+       }
+}