Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
4.7 KiB

  1. #ifndef __PERFTIMR_HXX__
  2. #define __PERFTIMR_HXX__
  3. //+-------------------------------------------------------------------------
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  7. //
  8. // File: perftimr.hxx
  9. //
  10. // Contents: Performance Timer class
  11. //
  12. // Classes: CPerfTimer
  13. //
  14. // History: 31-Jan-94 PeterWi Created.
  15. //
  16. // Notes: -- the timer will assert if you don't call an End()
  17. // for each Start() [except for calling Reset() or the destructor]
  18. //
  19. // -- change DECIMAL_PLACES to the number you want to print.
  20. // Operations will still be done internally with maximum precision.
  21. //
  22. // -- maximum precision on intel seems to be 1/1,193,000
  23. // or 1 millisecond
  24. //
  25. //
  26. // Usage:
  27. //
  28. // Say you want to time operations:
  29. // 1) A
  30. // 2) A and B
  31. // 3) 3 repetitions of (A and B)
  32. //
  33. // ...
  34. // cperftimer totaltimer;
  35. //
  36. // for (3 reps)
  37. // {
  38. // CPerfTimer timer;
  39. //
  40. // timer.Start();
  41. //
  42. // operation A
  43. //
  44. // timer.End().Add();
  45. //
  46. // printf("time for A is %ws\n", timer.FormatElapsedTime());
  47. //
  48. // timer.Start();
  49. //
  50. // operation B
  51. //
  52. // timer.End().Add();
  53. //
  54. // printf("time for A+B is %ws\n", timer.FormatTotalTime());
  55. //
  56. // totalTimer.Add(timer);
  57. // }
  58. //
  59. // printf("time for 3 reps of A+B is %ws\n", totalTimer.FormatTotalTime());
  60. //
  61. // where the last printf() would print something like:
  62. //
  63. // "time for 3 reps of A+B is 3.234s"
  64. //
  65. //--------------------------------------------------------------------------
  66. #define DECIMAL_PLACES 5 // number of decimal places you want
  67. class CPerfTimer
  68. {
  69. private:
  70. LONGLONG
  71. GetLowTickCount(void)
  72. {
  73. _nt = NtQueryPerformanceCounter(&_liConvert1, &_liConvert2);
  74. _liCount = _liConvert1.QuadPart;
  75. _liFreq = _liConvert2.QuadPart;
  76. return _liCount;
  77. }
  78. void
  79. _CheckState(void)
  80. {
  81. if ( _fStarted )
  82. {
  83. ASSERT(!"in middle of timing -- need to stop timer\n");
  84. }
  85. }
  86. WCHAR *
  87. _TimeToString(LONGLONG & liTime)
  88. {
  89. LONGLONG liSeconds;
  90. LONGLONG liRemainder;
  91. LONGLONG liBigRemainder;
  92. LONGLONG liDecimal;
  93. liSeconds = liTime / _liFreq;
  94. liRemainder = liTime % _liFreq;
  95. liBigRemainder = liRemainder * (LONGLONG) _ulMult;
  96. liDecimal = liBigRemainder / _liFreq;
  97. wsprintf(_wszTime, _wszFormat, (LONG)liSeconds, (LONG)liDecimal);
  98. return _wszTime;
  99. }
  100. LONGLONG _liCount;
  101. LONGLONG _liFreq;
  102. LONGLONG _totalTime;
  103. LONGLONG _startTime;
  104. LONGLONG _endTime;
  105. LONGLONG _elapsedTime;
  106. LARGE_INTEGER _liConvert1;
  107. LARGE_INTEGER _liConvert2;
  108. NTSTATUS _nt;
  109. ULONG _ulMult;
  110. BOOLEAN _fStarted;
  111. WCHAR _wszTime[20];// allow max of "time:99999.999s" and NULL
  112. WCHAR _wszFormat[20];
  113. public:
  114. CPerfTimer()
  115. {
  116. _ulMult = 1;
  117. for ( ULONG j = 0; j < DECIMAL_PLACES; j++ )
  118. {
  119. _ulMult *= 10;
  120. }
  121. wsprintf(_wszFormat, L"%ws%dlus", L"%lu.%0", DECIMAL_PLACES);
  122. Reset();
  123. }
  124. CPerfTimer &
  125. Reset(void)
  126. {
  127. _fStarted = FALSE;
  128. _totalTime = 0;
  129. _elapsedTime = 0;
  130. _endTime = _startTime = GetLowTickCount();
  131. return *this;
  132. }
  133. CPerfTimer &
  134. Start(void)
  135. {
  136. _CheckState();
  137. _fStarted = TRUE;
  138. _startTime = GetLowTickCount();
  139. return *this;
  140. }
  141. CPerfTimer &
  142. End(void)
  143. {
  144. _endTime = GetLowTickCount();
  145. if ( !_fStarted )
  146. {
  147. ASSERT(!"end without starting timer\n");
  148. }
  149. _fStarted = FALSE;
  150. _elapsedTime = _endTime - _startTime;
  151. return *this;
  152. }
  153. CPerfTimer &
  154. Add(void)
  155. {
  156. _CheckState();
  157. _totalTime = _totalTime + _elapsedTime;
  158. return *this;
  159. }
  160. CPerfTimer &
  161. Add(const CPerfTimer & timer)
  162. {
  163. _CheckState();
  164. _totalTime = _totalTime + timer.TotalTime();
  165. return *this;
  166. }
  167. LONGLONG
  168. TotalTime(void) const { return _totalTime; }
  169. LONGLONG
  170. ElapsedTime(void) const { return _elapsedTime; }
  171. LONGLONG
  172. TimeUnitsPerSecond(void) const { return _liFreq; }
  173. WCHAR *
  174. FormatTotalTime(void) { return _TimeToString(_totalTime); };
  175. WCHAR *
  176. FormatElapsedTime(void) { return _TimeToString(_elapsedTime); };
  177. }; // CPerfTimer
  178. #endif // __PERFTIMR_HXX__