我需要在Free Pascal中实现简单的性能基准测试.在Delphi中,我正在使用诊断单元的TStopWatch记录,我可以在Free Pascal / Lazarus中使用什么?
解决方法
这是Delphi在线doc的一个实现模型:
{ High frequency stop watch implemntation. copyright (c) 2012 by Inoussa OUEDRAOGO This source code is distributed under the Library GNU General Public License with the following modification: - object files and libraries linked into an application may be distributed without source code. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or fitness FOR A PARTIculaR PURPOSE. **********************************************************************} {$IFDEF FPC} {$mode objfpc}{$H+} {$modeswitch advancedrecords} {$ENDIF} {$IFDEF MSWINDOWS} {$IFNDEF WINDOWS} {$DEFINE WINDOWS} {$ENDIF WINDOWS} {$ENDIF MSWINDOWS} unit stopwatch; interface uses SysUtils {$IFDEF LINUX},unixtype,linux {$ENDIF LINUX} ; type { TStopWatch } TStopWatch = record private const C_THOUSAND = 1000; C_MILLION = C_THOUSAND * C_THOUSAND; C_BILLION = C_THOUSAND * C_THOUSAND * C_THOUSAND; TicksPerNanoSecond = 100; TicksPerMilliSecond = 10000; TicksPerSecond = C_BILLION div 100; Type TBaseMesure = {$IFDEF WINDOWS} Int64; {$ENDIF WINDOWS} {$IFDEF LINUX} TTimeSpec; {$ENDIF LINUX} strict private class var FFrequency : Int64; class var FIsHighResolution : Boolean; strict private FElapsed : Int64; FRunning : Boolean; FStartPosition : TBaseMesure; strict private procedure CheckInitialization();inline; function GetElapsedMilliseconds: Int64; function GetElapsedTicks: Int64; public class function Create() : TStopWatch;static; class function StartNew() : TStopWatch;static; class property Frequency : Int64 read FFrequency; class property IsHighResolution : Boolean read FIsHighResolution; procedure Reset(); procedure Start(); procedure Stop(); property ElapsedMilliseconds : Int64 read GetElapsedMilliseconds; property ElapsedTicks : Int64 read GetElapsedTicks; property IsRunning : Boolean read FRunning; end; resourcestring sstopWatchnotinitialized = 'The StopWatch is not initialized.'; implementation {$IFDEF WINDOWS} uses Windows; {$ENDIF WINDOWS} { TStopWatch } class function TStopWatch.Create(): TStopWatch; {$IFDEF LINUX} var r : TBaseMesure; {$ENDIF LINUX} begin if (FFrequency = 0) then begin {$IFDEF WINDOWS} FIsHighResolution := QueryPerformanceFrequency(FFrequency); {$ENDIF WINDOWS} {$IFDEF LINUX} FIsHighResolution := (clock_getres(CLOCK_MONOTONIC,@r) = 0); FIsHighResolution := FIsHighResolution and (r.tv_nsec <> 0); if (r.tv_nsec <> 0) then FFrequency := C_BILLION div r.tv_nsec; {$ENDIF LINUX} end; FillChar(Result,SizeOf(Result),0); end; class function TStopWatch.StartNew() : TStopWatch; begin Result := TStopWatch.Create(); Result.Start(); end; procedure TStopWatch.CheckInitialization(); begin if (FFrequency = 0) then raise Exception.Create(sstopWatchnotinitialized); end; function TStopWatch.GetElapsedMilliseconds: Int64; begin {$IFDEF WINDOWS} Result := ElapsedTicks * TicksPerMilliSecond; {$ENDIF WINDOWS} {$IFDEF LINUX} Result := FElapsed div C_MILLION; {$ENDIF LINUX} end; function TStopWatch.GetElapsedTicks: Int64; begin CheckInitialization(); {$IFDEF WINDOWS} Result := (FElapsed * TicksPerSecond) div FFrequency; {$ENDIF WINDOWS} {$IFDEF LINUX} Result := FElapsed div TicksPerNanoSecond; {$ENDIF LINUX} end; procedure TStopWatch.Reset(); begin Stop(); FElapsed := 0; FillChar(FStartPosition,SizeOf(FStartPosition),0); end; procedure TStopWatch.Start(); begin if FRunning then exit; FRunning := True; {$IFDEF WINDOWS} QueryPerformanceCounter(FStartPosition); {$ENDIF WINDOWS} {$IFDEF LINUX} clock_gettime(CLOCK_MONOTONIC,@FStartPosition); {$ENDIF LINUX} end; procedure TStopWatch.Stop(); var locEnd : TBaseMesure; s,n : Int64; begin if not FRunning then exit; FRunning := False; {$IFDEF WINDOWS} QueryPerformanceCounter(locEnd); FElapsed := FElapsed + (UInt64(locEnd) - UInt64(FStartPosition)); {$ENDIF WINDOWS} {$IFDEF LINUX} clock_gettime(CLOCK_MONOTONIC,@locEnd); if (locEnd.tv_nsec < FStartPosition.tv_nsec) then begin s := locEnd.tv_sec - FStartPosition.tv_sec - 1; n := C_BILLION + locEnd.tv_nsec - FStartPosition.tv_nsec; end else begin s := locEnd.tv_sec - FStartPosition.tv_sec; n := locEnd.tv_nsec - FStartPosition.tv_nsec; end; FElapsed := FElapsed + (s * C_BILLION) + n; {$ENDIF LINUX} end; end.
原文地址:https://www.jb51.cc/delphi/101402.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。