Pau*_*l L 5 delphi performancecounter
您好我使用QueryperformanceCounter来计算Delphi中的代码块.出于某种原因,使用QueryPerformanceCounter获得的毫秒数与使用秒表的挂钟时间完全不同.例如,秒表给了我大约33秒,这似乎是正确的,如果不准确,但使用QueryPerofomanceCounter将给我一个像500毫秒的数字.
通过我的代码,我可以看到QueryPerformanceFrequency给我正确的CPU CPU频率,CoreG E6600的2.4G.因此,如果刻度号是正确的,(tick number / Freq) * 1000应该给我正确的代码执行时间,但为什么不呢?
我知道,对于我想要计时的代码,QeuryPerformanceCounter可能过度杀死,因为花了几秒而不是百万秒,但我更感兴趣的是了解挂钟和QueryPerormanceCounter之间时差的原因.
我的硬件是E6600 Core2,操作系统是Windows 7 X64,如果它是相关的.
unit PerformanceTimer;
interface
uses Windows, SysUtils, DateUtils;
type TPerformanceTimer = class
private
fFrequency : TLargeInteger;
fIsRunning: boolean;
fIsHighResolution: boolean;
fStartCount, FstopCount : TLargeInteger;
procedure SetTickStamp(var lInt : TLargeInteger) ;
function GetElapsedTicks: TLargeInteger;
function GetElapsedMiliseconds: TLargeInteger;
public
constructor Create(const startOnCreate : boolean = false) ;
procedure Start;
procedure Stop;
property IsHighResolution : boolean read fIsHighResolution;
property ElapsedTicks : TLargeInteger read GetElapsedTicks;
property ElapsedMiliseconds : TLargeInteger read GetElapsedMiliseconds;
property IsRunning : boolean read fIsRunning;
end;
implementation
constructor TPerformanceTimer.Create(const startOnCreate : boolean = false) ;
begin
inherited Create;
fIsRunning := false;
fIsHighResolution := QueryPerformanceFrequency(fFrequency) ;
if NOT fIsHighResolution then
fFrequency := MSecsPerSec;
if startOnCreate then
Start;
end;
function TPerformanceTimer.GetElapsedTicks: TLargeInteger;
begin
result := fStopCount - fStartCount;
end;
procedure TPerformanceTimer.SetTickStamp(var lInt : TLargeInteger) ;
begin
if fIsHighResolution then
QueryPerformanceCounter(lInt)
else
lInt := MilliSecondOf(Now) ;
end;
function TPerformanceTimer.GetElapsedMiliseconds: TLargeInteger;
begin
result := (MSecsPerSec * (fStopCount - fStartCount)) div fFrequency;
end;
procedure TPerformanceTimer.Start;
begin
SetTickStamp(fStartCount) ;
fIsRunning := true;
end;
procedure TPerformanceTimer.Stop;
begin
SetTickStamp(fStopCount) ;
fIsRunning := false;
end;
end.
Run Code Online (Sandbox Code Playgroud)
这段代码只适合我,也许你可以尝试一下:
var
ifrequency, icount1, icount2: Int64;
fmsec: Double;
begin
QueryPerformanceFrequency(ifrequency);
QueryPerformanceCounter(icount1);
Sleep(500);
QueryPerformanceCounter(icount2);
fmsec := 1000 * ((icount2 - icount1) / ifrequency);
end;
Run Code Online (Sandbox Code Playgroud)
fmsec 约为 499.6 或类似的值。
注意:对于小数字,不要依赖 Now 或 TickCount:它们的间隔约为 10 毫秒(取决于 Windows 版本)!因此,如果您使用 Now 和 DateUtils.MillisecondsBetween,“sleep(10)”的持续时间可能会给出 0ms
注 2:不要长时间依赖 QueryPerformanceCounter,因为一天中时间可能会慢慢消失(每分钟大约 1 毫秒差异)
您应该发布一个代码片段来说明问题......但我会假设您有一个错误:
Milliseconds := 1000 * ((StopCount - StartCount) / Frequency);
Run Code Online (Sandbox Code Playgroud)
如果您与秒表进行比较,您可能会采取更简单的路线,只需捕获前后的 TDateTime(通过使用Now()),然后使用 DateUtils MilliSecondSpan()方法来计算差值:
var
MyStartDate:TDateTime;
MyStopDate:TDateTime;
MyTiming:Double;
begin
MyStartDate := Now();
DoSomethingYouWantTimed();
MyStopDate := Now();
MyTiming := MilliSecondSpan(MyStopDate, MyStartDate);
DoSomethingWithTiming(MyTiming);
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4990 次 |
| 最近记录: |