Interessant

Meet nauwkeurig de verstreken tijd met Delphi Performance Counter

Meet nauwkeurig de verstreken tijd met Delphi Performance Counter

Voor routinematige desktopdatabasetoepassingen maakt het toevoegen van een seconde aan de uitvoeringstijd van een taak zelden een verschil voor eindgebruikers - maar wanneer u miljoenen boombladeren moet verwerken of miljarden unieke willekeurige getallen moet genereren, wordt de snelheid van uitvoering belangrijker.

Time-out van uw code

In sommige toepassingen zijn zeer nauwkeurige, zeer nauwkeurige tijdmeetmethoden belangrijk en gelukkig biedt Delphi een krachtige teller om deze tijden te kwalificeren.

RTL's gebruiken NuFunctie

Eén optie gebruikt de Nu-functie. Nu, gedefinieerd in de sysutils eenheid, geeft de huidige systeemdatum en -tijd terug.

Een paar regels code meten de verstreken tijd tussen het "starten" en "stoppen" van een bepaald proces:

var

start, stop, verstreken: TDateTime;

beginnen

start: = Nu;

// TimeOutThis ();

stop: = Nu;

verlopen: = stop - start;

einde;

De functie Nu retourneert de huidige systeemdatum en -tijd die tot 10 milliseconden (Windows NT en hoger) of 55 milliseconden (Windows 98) nauwkeurig is.

Voor zeer kleine intervallen is de precisie van "Nu" soms niet genoeg.

Met behulp van Windows API GetTickCount

Voor nog preciezere gegevens gebruikt u de GetTickCount Windows API-functie. GetTickCount haalt het aantal milliseconden op dat is verstreken sinds het systeem is opgestart, maar de functie heeft slechts de precisie van 1 ms en is mogelijk niet altijd nauwkeurig als de computer lange tijd ingeschakeld blijft.

De verstreken tijd wordt opgeslagen als een DWORD-waarde (32-bits). Daarom zal de tijd rondlopen tot nul als Windows 49,7 dagen continu wordt uitgevoerd.

var

start, stop, verstreken: kardinaal;

beginnen

start: = GetTickCount;

// TimeOutThis ();

stop: = GetTickCount;

verlopen: = stop - start; // millisecondsend;

GetTickCount is ook beperkt tot de nauwkeurigheid van de systeemtimer (10/55 ms).

Hoge precisie Timing van uw code

Als uw pc een teller met hoge resolutie ondersteunt, gebruik dan de QueryPerformanceFrequency Windows API-functie om de frequentie uit te drukken, in tellingen per seconde. De waarde van de telling is afhankelijk van de processor.

De QueryPerformanceCounter functie haalt de huidige waarde van de prestatieteller met hoge resolutie op. Door deze functie aan het begin en einde van een codedeel aan te roepen, gebruikt een toepassing de teller als een timer met hoge resolutie.

De nauwkeurigheid van timers met hoge resolutie is ongeveer een paar honderd nanoseconden. Een nanoseconde is een tijdseenheid die 0,000000001 seconden vertegenwoordigt - of 1 miljardste van een seconde.

TStopWatch: Delphi Implementatie van een teller met hoge resolutie

Met een knipoog naar .Net-naamgevingsconventies, een teller zoals TStopWatch biedt een Delphi-oplossing met hoge resolutie voor nauwkeurige tijdmetingen.

TStopWatch meet de verstreken tijd door timertikken in het onderliggende timermechanisme te tellen.

  • De IsHighResolution eigenschap geeft aan of de timer is gebaseerd op een prestatieteller met hoge resolutie.
  • De Begin methode begint met het meten van de verstreken tijd.
  • De Hou op methode stopt met het meten van de verstreken tijd.
  • De ElapsedMilliseconds eigenschap krijgt de totale verstreken tijd in milliseconden.
  • De verstreken eigenschap krijgt de totale verstreken tijd in timertikken.

eenheid Stopwatch;

interface

toepassingen Windows, SysUtils, DateUtils;

type TStopWatch = klasse

  privaat

fFrequentie: TLargeInteger;

fIsRunning: boolean;

fIsHighResolution: boolean;

fStartCount, fStopCount: TLargeInteger;

    procedure SetTickStamp (var lInt: TLargeInteger);
    

functie GetElapsedTicks: TLargeInteger;
    

functie GetElapsedMilliseconds: TLargeInteger;
    

functie GetElapsed: string;
  

openbaar

    bouwer Create (const startOnCreate: boolean = false);
    

procedure Begin;
    

procedure Hou op;
    

eigendom IsHighResolution: boolean lezen fIsHighResolution;
    

eigendom ElapsedTicks: TLargeInteger lezen GetElapsedTicks;
    

eigendom ElapsedMilliseconds: TLargeInteger lezen GetElapsedMilliseconds;
    

eigendom Verstreken: string lezen GetElapsed;
    

eigendom IsRunning: boolean lezen fIsRunning;
  

einde;

implementatie

bouwer TStopWatch.Create (const startOnCreate: boolean = false);

beginnen

geërfd maken;

fIsRunning: = false;

fIsHighResolution: = QueryPerformanceFrequency (fFrequency);

  als niet fIsHighResolution vervolgens fFrequency: = MSecsPerSec;
  

als startOnCreate vervolgens Begin;

einde;

functie TStopWatch.GetElapsedTicks: TLargeInteger;

beginnen

resultaat: = fStopCount - fStartCount;

einde;

procedure TStopWatch.SetTickStamp (var lInt: TLargeInteger);

beginnen

  als fIsHighResolution vervolgens

QueryPerformanceCounter (pluizen)

anders

lInt: = MilliSecondOf (nu);

einde;

functie TStopWatch.GetElapsed: draad;

var

dt: TDateTime;

beginnen

dt: = ElapsedMilliseconds / MSecsPerSec / SecsPerDay;

resultaat: = Indeling ('% d dagen,% s', trunc (dt), FormatDateTime ('hh: nn: ss.z', Frac (dt)));

einde;

functie TStopWatch.GetElapsedMilliseconds: TLargeInteger;

beginnen

resultaat: = (MSecsPerSec * (fStopCount - fStartCount)) div fFrequency;

einde;

procedure TStopWatch.Start;

beginnen

SetTickStamp (fStartCount);

fIsRunning: = true;

einde;

procedure TStopWatch.Stop;

beginnen

SetTickStamp (fStopCount);

fIsRunning: = false;

einde;

einde.

Hier is een voorbeeld van gebruik:

var

sw: TStopWatch;

verstreken Milliseconden: kardinaal;

beginnen

sw: = TStopWatch.Create ();

  proberen

sw.Start;

    // TimeOutThisFunction ()

sw.Stop;

elapsedMilliseconds: = sw.ElapsedMilliseconds;

  Tenslotte

sw.Free;

  einde;

einde;

Bekijk de video: Handleiding TLC750i (November 2020).