什么是Free Pascal相当于Delphi的TStopWatch?

前端之家收集整理的这篇文章主要介绍了什么是Free Pascal相当于Delphi的TStopWatch?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要在Free Pascal中实现简单的性能基准测试.在Delphi中,我正在使用诊断单元的TStopWatch记录,我可以在Free Pascal / Lazarus中使用什么?

解决方法

这是Delphi在线doc的一个实现模型:
  1. { High frequency stop watch implemntation.
  2. Copyright (c) 2012 by Inoussa OUEDRAOGO
  3.  
  4. This source code is distributed under the Library GNU General Public License
  5. with the following modification:
  6.  
  7. - object files and libraries linked into an application may be
  8. distributed without source code.
  9.  
  10. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12.  
  13. **********************************************************************}
  14.  
  15. {$IFDEF FPC}
  16. {$mode objfpc}{$H+}
  17. {$modeswitch advancedrecords}
  18. {$ENDIF}
  19.  
  20. {$IFDEF MSWINDOWS}
  21. {$IFNDEF WINDOWS}
  22. {$DEFINE WINDOWS}
  23. {$ENDIF WINDOWS}
  24. {$ENDIF MSWINDOWS}
  25.  
  26. unit stopwatch;
  27.  
  28. interface
  29. uses
  30. SysUtils
  31. {$IFDEF LINUX},unixtype,linux
  32. {$ENDIF LINUX}
  33. ;
  34.  
  35. type
  36.  
  37. { TStopWatch }
  38.  
  39. TStopWatch = record
  40. private
  41. const
  42. C_THOUSAND = 1000;
  43. C_MILLION = C_THOUSAND * C_THOUSAND;
  44. C_BILLION = C_THOUSAND * C_THOUSAND * C_THOUSAND;
  45. TicksPerNanoSecond = 100;
  46. TicksPerMilliSecond = 10000;
  47. TicksPerSecond = C_BILLION div 100;
  48. Type
  49. TBaseMesure =
  50. {$IFDEF WINDOWS}
  51. Int64;
  52. {$ENDIF WINDOWS}
  53. {$IFDEF LINUX}
  54. TTimeSpec;
  55. {$ENDIF LINUX}
  56. strict private
  57. class var FFrequency : Int64;
  58. class var FIsHighResolution : Boolean;
  59. strict private
  60. FElapsed : Int64;
  61. FRunning : Boolean;
  62. FStartPosition : TBaseMesure;
  63. strict private
  64. procedure CheckInitialization();inline;
  65. function GetElapsedMilliseconds: Int64;
  66. function GetElapsedTicks: Int64;
  67. public
  68. class function Create() : TStopWatch;static;
  69. class function StartNew() : TStopWatch;static;
  70. class property Frequency : Int64 read FFrequency;
  71. class property IsHighResolution : Boolean read FIsHighResolution;
  72. procedure Reset();
  73. procedure Start();
  74. procedure Stop();
  75. property ElapsedMilliseconds : Int64 read GetElapsedMilliseconds;
  76. property ElapsedTicks : Int64 read GetElapsedTicks;
  77. property IsRunning : Boolean read FRunning;
  78. end;
  79.  
  80. resourcestring
  81. sStopWatchNotInitialized = 'The StopWatch is not initialized.';
  82.  
  83. implementation
  84. {$IFDEF WINDOWS}
  85. uses
  86. Windows;
  87. {$ENDIF WINDOWS}
  88.  
  89. { TStopWatch }
  90.  
  91. class function TStopWatch.Create(): TStopWatch;
  92. {$IFDEF LINUX}
  93. var
  94. r : TBaseMesure;
  95. {$ENDIF LINUX}
  96. begin
  97. if (FFrequency = 0) then begin
  98. {$IFDEF WINDOWS}
  99. FIsHighResolution := QueryPerformanceFrequency(FFrequency);
  100. {$ENDIF WINDOWS}
  101. {$IFDEF LINUX}
  102. FIsHighResolution := (clock_getres(CLOCK_MONOTONIC,@r) = 0);
  103. FIsHighResolution := FIsHighResolution and (r.tv_nsec <> 0);
  104. if (r.tv_nsec <> 0) then
  105. FFrequency := C_BILLION div r.tv_nsec;
  106. {$ENDIF LINUX}
  107. end;
  108. FillChar(Result,SizeOf(Result),0);
  109. end;
  110.  
  111. class function TStopWatch.StartNew() : TStopWatch;
  112. begin
  113. Result := TStopWatch.Create();
  114. Result.Start();
  115. end;
  116.  
  117. procedure TStopWatch.CheckInitialization();
  118. begin
  119. if (FFrequency = 0) then
  120. raise Exception.Create(sStopWatchNotInitialized);
  121. end;
  122.  
  123. function TStopWatch.GetElapsedMilliseconds: Int64;
  124. begin
  125. {$IFDEF WINDOWS}
  126. Result := ElapsedTicks * TicksPerMilliSecond;
  127. {$ENDIF WINDOWS}
  128. {$IFDEF LINUX}
  129. Result := FElapsed div C_MILLION;
  130. {$ENDIF LINUX}
  131. end;
  132.  
  133. function TStopWatch.GetElapsedTicks: Int64;
  134. begin
  135. CheckInitialization();
  136. {$IFDEF WINDOWS}
  137. Result := (FElapsed * TicksPerSecond) div FFrequency;
  138. {$ENDIF WINDOWS}
  139. {$IFDEF LINUX}
  140. Result := FElapsed div TicksPerNanoSecond;
  141. {$ENDIF LINUX}
  142. end;
  143.  
  144. procedure TStopWatch.Reset();
  145. begin
  146. Stop();
  147. FElapsed := 0;
  148. FillChar(FStartPosition,SizeOf(FStartPosition),0);
  149. end;
  150.  
  151. procedure TStopWatch.Start();
  152. begin
  153. if FRunning then
  154. exit;
  155. FRunning := True;
  156. {$IFDEF WINDOWS}
  157. QueryPerformanceCounter(FStartPosition);
  158. {$ENDIF WINDOWS}
  159. {$IFDEF LINUX}
  160. clock_gettime(CLOCK_MONOTONIC,@FStartPosition);
  161. {$ENDIF LINUX}
  162. end;
  163.  
  164. procedure TStopWatch.Stop();
  165. var
  166. locEnd : TBaseMesure;
  167. s,n : Int64;
  168. begin
  169. if not FRunning then
  170. exit;
  171. FRunning := False;
  172. {$IFDEF WINDOWS}
  173. QueryPerformanceCounter(locEnd);
  174. FElapsed := FElapsed + (UInt64(locEnd) - UInt64(FStartPosition));
  175. {$ENDIF WINDOWS}
  176. {$IFDEF LINUX}
  177. clock_gettime(CLOCK_MONOTONIC,@locEnd);
  178. if (locEnd.tv_nsec < FStartPosition.tv_nsec) then begin
  179. s := locEnd.tv_sec - FStartPosition.tv_sec - 1;
  180. n := C_BILLION + locEnd.tv_nsec - FStartPosition.tv_nsec;
  181. end else begin
  182. s := locEnd.tv_sec - FStartPosition.tv_sec;
  183. n := locEnd.tv_nsec - FStartPosition.tv_nsec;
  184. end;
  185. FElapsed := FElapsed + (s * C_BILLION) + n;
  186. {$ENDIF LINUX}
  187. end;
  188.  
  189. end.

猜你在找的Delphi相关文章