Ross Levis Wrote:
>>I have found TTimer to work down to about 8 to 10ms as a minimum, 
>>definately well less than 55ms.

The standard TTimer can only be guaranteed to be accurate to 55
milliseconds as it utilises the PC's clock timer. You may get better
results but it will depend upon the PC.

For greater accuracy you can use the Windows API's
QueryPerformanceCounter which can be accurate to 1,193,180 counts per
second on a Pentium and above but will definitely give you millisecond
accuracy on Win98 and above.

I posted an article here
http://www.delphi3000.com/articles/article_1347.asp some time back which
simplifies the API usage by providing a Delphi interface to utilise for
performance logging code.

It works with Delphi 3, 4 & 5 and although not tested should work with
later versions too.

Code from the article as follows:
---------------------------------
The following unit implements a HighResTimer object to simplify use of
the WinAPI QueryPerformanceCounter and QueryPerformanceFrequency High
resolution counter functions. This can then be extended to provide
WriteToFile, LogToDB functionality etc... 

Just add to your uses clause then create an instance of THighResTimer
whenever you need it. 

Note: Contains IFDEFs to handle the change to TLargeInteger in Delphi
versions 3, 4 & 5+ 

unit HighResTimer; 
{********************************************************************* 
********************************************************************** 
*  Comments: Provides an object to access Window's high resolution
performance 
*            timer mechanism. 
*  Notes:    The accuracy provided by the functions Now and Time are 
*            limited to 55ms as they use the PC's clock timer. The 
*            Window's API gives access to a hardware based high 
*            resolution performance timer that counts 1,193,180 times 
*            per second (at least it does on WinNT with a Pentium) to 
*            retrieve more accurate timings. 
* 
*  Help:     The HighResTimer once created just needs to be started 
*            before performing an action then stopped once the 
*            actions been performed. The time taken can be retrieved 
*            as a TDateTime by calling the Time property or as an 
*            integer by calling the Ticks property. 
*            Example: 
*              var 
*                MyHighResTimer: THighResTimer; 
*                i, j: Integer; 
*              begin 
*                MyHighResTimer := THighResTimer.Create; 
*                try 
*                  MyHighResTimer.Start; 
*                  for i := 0 to 1000 do 
*                  begin 
*                    j := i; 
*                  end; 
*                  MyHighResTimer.Stop; 
*                  ShowMessage(Format('Operation took Time:%8.8f 
*                                     Ticks:%d',[FHighResTimer.Time, 
*                                     FHighResTimer.Ticks])); 
*                finally 
*                  MyHighResTimer.Free; 
*                end; 
*              end; 
* 
* 
********************************************************************** 
**********************************************************************} 

interface 

uses 
  Windows; 

type 
  THighResTimer = Class(TObject) 
  private 
    FStartCount: TLargeInteger; 
    FStopCount: TLargeInteger; 
    FTicks: Cardinal; 
    FTime: TDateTime; 
    function GetTicks: Cardinal; 
    function GetTime: TDateTime; 
  public 
    constructor Create; virtual; 
    destructor Destroy; override; 
    procedure Start; virtual; 
    procedure Stop; virtual; 
    property Ticks: Cardinal read GetTicks; 
    property Time: TDateTime read GetTime; 
  end; 

const 
  TICK_MILLISECOND = 1000; 
  DATE_TIME_MILLISECOND = 0.00001; 

var 
  GHighResFrequency: TLargeInteger; 

implementation 

{ THighResTimer } 

constructor THighResTimer.Create; 
begin 
  inherited Create; 
{$IFDEF VER130} 
  FStartCount := 0; 
  FStopCount := 0; 
{$ELSE} 
  FStartCount.QuadPart := 0; 
  FStopCount.QuadPart := 0; 
{$ENDIF} 
end; 

destructor THighResTimer.Destroy; 
begin 
  {} 
  inherited; 
end; 

{ Note: The use of cardinal means this can only cope with a maximum 49
day gap} 
function THighResTimer.GetTicks: Cardinal; 
var 
  countTaken: TLargeInteger; 
  countTicks: Double; 
begin 
{$IFDEF VER130} 
  countTaken := FStopCount - FStartCount; 
  { Use double, instead of integer division to arrive at an equal value
as 
    in GetTime, below} 
  countTicks := (countTaken / GHighResFrequency) * TICK_MILLISECOND; 
{$ELSE} 
  countTaken.QuadPart := FStopCount.QuadPart - FStartCount.QuadPart; 
  countTicks := (countTaken.QuadPart / GHighResFrequency.QuadPart) * 
    TICK_MILLISECOND; 
{$ENDIF} 
  Result := Round(countTicks); 
end; 

function THighResTimer.GetTime: TDateTime; 
var 
  countTaken: Double; 
begin 
{$IFDEF VER130} 
  countTaken := FStopCount - FStartCount; 
  Result := (countTaken / GHighResFrequency) * DATE_TIME_MILLISECOND; 
{$ELSE} 
  countTaken := FStopCount.QuadPart - FStartCount.QuadPart; 
  Result := (countTaken / GHighResFrequency.QuadPart) *
DATE_TIME_MILLISECOND; 
{$ENDIF} 
end; 

procedure THighResTimer.Start; 
begin 
  QueryPerformanceCounter(FStartCount); 
  FStopCount := FStartCount; 
end; 

procedure THighResTimer.Stop; 
begin 
  QueryPerformanceCounter(FStopCount); 
end; 

initialization 
  QueryPerformanceFrequency(GHighResFrequency); 
end. 


Michael Darling
Senior Solutions Developer
ROOM Solutions Ltd
mailto:[EMAIL PROTECTED]


-----Original Message-----
From: Ross Levis [mailto:[EMAIL PROTECTED] 
Sent: 31 March 2006 08:22
To: Borland's Delphi Discussion List
Subject: Re: More accurate timers


I have found TTimer to work down to about 8 to 10ms as a minimum, 
definately well less than 55ms.

Ross.

----- Original Message ----- 
From: "John Dammeyer" <[EMAIL PROTECTED]>
To: "'Borland's Delphi Discussion List'" <[email protected]>
Sent: Friday, March 31, 2006 4:13 PM
Subject: More accurate timers


Hi all,

The standard Delphi TTimer appears to be fairly useful since it allows 
time
delays in 1mS steps but apparently resolves to a 55mS granularity.  A 
while
back I tried a timer I found on the WEB but couldn't get it to work with
Delphi-5.

If you are using a better timer, which one and what sort of issues are 
there
with them?

Thanks,

John Dammeyer
*******************************************************************
CONFIDENTIALITY NOTICE/DISCLAIMER
This email and any attachments are confidential, protected by 
copyright/intellectual property rights and may be legally privileged. The 
information transmitted is intended only for the person or entity to which it 
is addressed.  If you are not the intended recipient, dissemination or copying 
of this email is prohibited.
If you have received this in error, please notify us by forwarding this email 
to the following address: [EMAIL PROTECTED] , and then delete the email 
completely from your system.
This email and any attachments have been scanned for computer viruses by a 
market leading anti-virus system. However, it is the responsibility of the 
recipient to conduct its own security measures. No responsibility is accepted 
by ROOM Solutions Limited for loss or damage arising from the receipt or use of 
this email and any attachments.
No responsibility is accepted by ROOM Solutions Limited for personal emails.
ROOM Solutions Ltd, http://www.roomsolutions.net
********************************************************************

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________
_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to