profiler.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #ifndef _PROFILER_H
  2. #define _PROFILER_H
  3. #include <bfc/wasabi_std.h>
  4. #include <bfc/string/bfcstring.h>
  5. #include <bfc/ptrlist.h>
  6. #ifdef NO_PROFILING
  7. #define PR_ENTER(msg)
  8. #define PR_LEAVE()
  9. #else
  10. #define _PR_ENTER(msg, line) { __Profiler __prx##line(msg)
  11. #define _PR_ENTER2(msg, msg2, line) { __Profiler __prx##line(msg, msg2)
  12. #define PR_ENTER(msg) _PR_ENTER(msg, line)
  13. #define PR_ENTER2(msg, msg2) _PR_ENTER2(msg, msg2, line)
  14. #define PR_LEAVE() }
  15. class __ProfilerEntry {
  16. public:
  17. __ProfilerEntry(const char *txt) { text = txt; totaltime = 0; totaln = 0; subcount = 0; lastcps = -1;}
  18. virtual ~__ProfilerEntry() {}
  19. void add(float ms) { totaltime += ms; totaln++;
  20. if (subcount == 0) {
  21. firstcall = Wasabi::Std::getTimeStampMS();
  22. }
  23. if (Wasabi::Std::getTimeStampMS() - firstcall < 1) {
  24. subcount++;
  25. } else {
  26. lastcps = subcount;
  27. subcount = 0;
  28. }
  29. }
  30. float getAverage() { if (totaln == 0) return 0; return totaltime / (float)totaln; }
  31. float getTotal() { return totaltime; }
  32. const char *getText() { return text; }
  33. int getLastCPS() { return lastcps; }
  34. private:
  35. float totaltime;
  36. int totaln;
  37. stdtimevalms firstcall;
  38. int lastcps;
  39. int subcount;
  40. String text;
  41. };
  42. class __ProfilerEntrySort {
  43. public:
  44. static int compareAttrib(const wchar_t *attrib, void *item) {
  45. return STRICMP((const char *)attrib, ((__ProfilerEntry*)item)->getText());
  46. }
  47. static int compareItem(void *i1, void *i2) {
  48. return STRICMP(((__ProfilerEntry*)i1)->getText(), ((__ProfilerEntry*)i2)->getText());
  49. }
  50. };
  51. extern COMEXP PtrListInsertSorted<__ProfilerEntry, __ProfilerEntrySort> __profiler_entries;
  52. extern COMEXP int __profiler_indent;
  53. class __ProfilerManager {
  54. public:
  55. static void log(const char *txt, float ms, float *total, float *average, int *lastcps) {
  56. int pos=-1;
  57. __ProfilerEntry *e = __profiler_entries.findItem((const wchar_t *)txt, &pos);
  58. if (pos < 0 || e == NULL) {
  59. e = new __ProfilerEntry(txt);
  60. __profiler_entries.addItem(e);
  61. }
  62. if (e != NULL) {
  63. e->add(ms);
  64. if (total != NULL) *total = e->getTotal();
  65. if (average != NULL) *average = e->getAverage();
  66. if (lastcps != NULL) *lastcps = e->getLastCPS();
  67. }
  68. }
  69. };
  70. #undef USE_TICK_COUNT
  71. class __Profiler {
  72. public:
  73. __Profiler(const char *text, const char *text2="") : str(text), str2(text2) {
  74. if (!str2.isempty()) str2 += " ";
  75. #ifdef USE_TICK_COUNT
  76. ts1 = GetTickCount();
  77. #else
  78. ts1 = Wasabi::Std::getTimeStampMS();
  79. #endif
  80. __profiler_indent++;
  81. }
  82. ~__Profiler() {
  83. __profiler_indent--;
  84. #ifdef USE_TICK_COUNT
  85. stdtimevalms ts2 = GetTickCount();
  86. #else
  87. stdtimevalms ts2 = Wasabi::Std::getTimeStampMS();
  88. #endif
  89. float ms = (float)((ts2 - ts1)
  90. #ifndef USE_TICK_COUNT
  91. *1000.0
  92. #endif
  93. );
  94. float total=0;
  95. float average=0;
  96. int lastcps=0;
  97. __ProfilerManager::log(str, ms, &total, &average, &lastcps);
  98. char buf[4096];
  99. if (lastcps >= 0)
  100. 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);
  101. else
  102. 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);
  103. #ifdef _WIN32
  104. OutputDebugStringA(buf);
  105. #else
  106. #warning port me
  107. #endif
  108. }
  109. private:
  110. String str, str2;
  111. stdtimevalms ts1;
  112. };
  113. #endif//!NO_PROFILING
  114. #endif