diff options
Diffstat (limited to 'Src/Wasabi/bfc/util/profiler.h')
-rw-r--r-- | Src/Wasabi/bfc/util/profiler.h | 128 |
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 |