GetTickCount is accurate to 1ms and very easy to use.  If you want 
microsecond or potentially even nanosecond.. use QueryPerformanceCounter.


With QueryPerformanceCounter yuu have to do a little math to convert it to 
real time, because the speed at which it runs varies depending on the speed 
of your processor...  but because of this, it can virtually get you accuracy 
down to the processor cycle . I use it to generate statistics for my 
scripting language. It allows me to add up the amount of time spent in each 
individual script function, no matter how insignificant, and then summarize 
where all the time was spent.  This gives me the ability to go through and 
choose which functions would benefit the most from optimizations.  If I 
tried to do this with GetTickCount, many of the simple functions would 
underflow because they take less than 1ms to compute and come out with 0ms 
time spent in the statistics, even if I called them 100,000 times.


Jason


----- Original Message ----- 
From: "Darling, Michael" <[EMAIL PROTECTED]>
To: "Borland's Delphi Discussion List" <[email protected]>
Sent: Friday, March 31, 2006 3:15 AM
Subject: RE: More accurate timers


> 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
> 

_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to