aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/util/profiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/util/profiler.h')
-rw-r--r--Src/Wasabi/bfc/util/profiler.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/util/profiler.h b/Src/Wasabi/bfc/util/profiler.h
new file mode 100644
index 00000000..e7b71e81
--- /dev/null
+++ b/Src/Wasabi/bfc/util/profiler.h
@@ -0,0 +1,128 @@
+#ifndef _PROFILER_H
+#define _PROFILER_H
+
+#include <bfc/wasabi_std.h>
+#include <bfc/string/bfcstring.h>
+#include <bfc/ptrlist.h>
+
+
+#ifdef NO_PROFILING
+#define PR_ENTER(msg)
+#define PR_LEAVE()
+#else
+
+#define _PR_ENTER(msg, line) { __Profiler __prx##line(msg)
+#define _PR_ENTER2(msg, msg2, line) { __Profiler __prx##line(msg, msg2)
+#define PR_ENTER(msg) _PR_ENTER(msg, line)
+#define PR_ENTER2(msg, msg2) _PR_ENTER2(msg, msg2, line)
+#define PR_LEAVE() }
+
+class __ProfilerEntry {
+ public:
+ __ProfilerEntry(const char *txt) { text = txt; totaltime = 0; totaln = 0; subcount = 0; lastcps = -1;}
+ virtual ~__ProfilerEntry() {}
+
+ void add(float ms) { totaltime += ms; totaln++;
+ if (subcount == 0) {
+ firstcall = Wasabi::Std::getTimeStampMS();
+ }
+ if (Wasabi::Std::getTimeStampMS() - firstcall < 1) {
+ subcount++;
+ } else {
+ lastcps = subcount;
+ subcount = 0;
+ }
+ }
+ float getAverage() { if (totaln == 0) return 0; return totaltime / (float)totaln; }
+ float getTotal() { return totaltime; }
+ const char *getText() { return text; }
+ int getLastCPS() { return lastcps; }
+
+ private:
+ float totaltime;
+ int totaln;
+ stdtimevalms firstcall;
+ int lastcps;
+ int subcount;
+ String text;
+};
+
+class __ProfilerEntrySort {
+public:
+ static int compareAttrib(const wchar_t *attrib, void *item) {
+ return STRICMP((const char *)attrib, ((__ProfilerEntry*)item)->getText());
+ }
+ static int compareItem(void *i1, void *i2) {
+ return STRICMP(((__ProfilerEntry*)i1)->getText(), ((__ProfilerEntry*)i2)->getText());
+ }
+};
+
+extern COMEXP PtrListInsertSorted<__ProfilerEntry, __ProfilerEntrySort> __profiler_entries;
+extern COMEXP int __profiler_indent;
+
+class __ProfilerManager {
+ public:
+ static void log(const char *txt, float ms, float *total, float *average, int *lastcps) {
+ int pos=-1;
+ __ProfilerEntry *e = __profiler_entries.findItem((const wchar_t *)txt, &pos);
+ if (pos < 0 || e == NULL) {
+ e = new __ProfilerEntry(txt);
+ __profiler_entries.addItem(e);
+ }
+ if (e != NULL) {
+ e->add(ms);
+ if (total != NULL) *total = e->getTotal();
+ if (average != NULL) *average = e->getAverage();
+ if (lastcps != NULL) *lastcps = e->getLastCPS();
+ }
+ }
+};
+
+#undef USE_TICK_COUNT
+
+class __Profiler {
+public:
+ __Profiler(const char *text, const char *text2="") : str(text), str2(text2) {
+ if (!str2.isempty()) str2 += " ";
+#ifdef USE_TICK_COUNT
+ ts1 = GetTickCount();
+#else
+ ts1 = Wasabi::Std::getTimeStampMS();
+#endif
+ __profiler_indent++;
+ }
+ ~__Profiler() {
+ __profiler_indent--;
+#ifdef USE_TICK_COUNT
+ stdtimevalms ts2 = GetTickCount();
+#else
+ stdtimevalms ts2 = Wasabi::Std::getTimeStampMS();
+#endif
+ float ms = (float)((ts2 - ts1)
+#ifndef USE_TICK_COUNT
+*1000.0
+#endif
+);
+ float total=0;
+ float average=0;
+ int lastcps=0;
+ __ProfilerManager::log(str, ms, &total, &average, &lastcps);
+ char buf[4096];
+ if (lastcps >= 0)
+ sprintf(buf, "%*sProfiler: %s: %s%6.4f ms (total: %6.4f ms, average: %6.4f ms, calls per second : %d)\n", __profiler_indent*4, " ", str.getValue(), str2.getValue(), ms, total, average, lastcps);
+ else
+ sprintf(buf, "%*sProfiler: %s: %s%6.4f ms (total: %6.4f ms, average: %6.4f ms)\n", __profiler_indent*4, " ", str.getValue(), str2.getValue(), ms, total, average);
+#ifdef _WIN32
+ OutputDebugStringA(buf);
+#else
+#warning port me
+#endif
+ }
+private:
+ String str, str2;
+ stdtimevalms ts1;
+};
+
+#endif//!NO_PROFILING
+
+#endif