Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Sonstiges (https://www.delphipraxis.net/45-library-sonstiges/)
-   -   Delphi TStopUhr - kleine Klasse zur Zeitmessung (https://www.delphipraxis.net/134663-tstopuhr-kleine-klasse-zur-zeitmessung.html)

Satty67 26. Mai 2009 16:53


TStopUhr - kleine Klasse zur Zeitmessung
 
Eigentlich etwas übertrieben, eine einfache Zeitmessung in eine Klasse zu packen. Die Stoppuhr war aber einer meiner ersten Übungs-Klassen, weshalb ich die immer wieder gerne nutze (aus dem Grund Stopp auch noch mit einem "p"). ;)

Heute hab' ich aus Langeweile die Klasse um zwei weitere Mess-Methoden erweitert, weshalb ich das ganze hier als Beispiel einstellen möchte.

TStopUhr misst die Zeitdifferenz zwischen Start und Stop in Millisekunden:
Delphi-Quellcode:
unit UStopUhr;

interface

type
  TStopUhrMethode = (su_DateTime, su_TickCount, su_Performance);
  TStopUhr = class
    private
      FStoppedTime : Int64;
      FStartValue  : Int64;
      FStopValue   : Int64;
      FStartTime   : TDateTime;
      FStopTime    : TDateTime;
      FMethode     : TStopUhrMethode;
      FMethodeInUse : TStopUhrMethode;
    protected
      function GetStoppedTimeStr: String;
    public
      Constructor Create;
      Destructor Destroy; Override;
      procedure Start;
      procedure Stop;
      property StartTime     : TDateTime read FStartTime;
      property StopTime      : TDateTime read FStopTime;
      property StoppedTime   : Int64 read FStoppedTime;
      property StoppedTimeStr : String read GetStoppedTimeStr;
      property MeasureMethode : TStopUhrMethode Read FMethode Write FMethode;
    end;

implementation

uses
  SysUtils, Windows;

var
  g_QPCFrequenz : Int64 = 0; // Vorschlag shmia, siehe Post

constructor TStopUhr.Create;
begin
  FStartTime   := Now;
  FStopTime    := FStartTime;
  FStoppedTime := 0;
  FStartValue  := 0;
  FStopValue   := 0;
  FMethode     := su_DateTime;
  FMethodeInUse := su_DateTime;
end;

destructor TStopUhr.Destroy;
begin
  inherited;
end;

function TStopUhr.GetStoppedTimeStr: String;
begin
  Result := Format('%.0n ms',[FStoppedTime / 1]);
end;

procedure TStopUhr.Start;
begin
  FMethodeInUse := FMethode;
  case FMethodeInUse of
    su_DateTime   : FStartTime := Now;
    su_TickCount  : FStartValue := GetTickCount;
    su_Performance : QueryPerformanceCounter(FStartValue);
  end;
end;

procedure TStopUhr.Stop;
const
  msPerDay = 86400000;
var
  Days, Hour, Min, Sec, MSec: Word;
begin
  case FMethodeInUse of
    su_DateTime   : begin
      FStopTime := Now;
      DecodeTime(FStopTime - FStartTime, Hour, Min, Sec, MSec);
      Days := Trunc(FStopTime) - Trunc(FStartTime);
      FStoppedTime := MSec + (Sec * 1000) + (Min * 60 * 1000) + (Hour * 60 * 60 * 1000) +
                      (Days * msPerDay);
    end;
    su_TickCount  : begin
      FStopValue := GetTickCount;
      FStoppedTime := FStopValue - FStartValue;
    end;
    su_Performance : begin
      QueryPerformanceCounter(FStopValue);
      FStoppedTime := (FStopValue - FStartValue) * 1000 div g_QPCFrequenz;
    end;
  end;
end;

initialization
   QueryPerformanceFrequency(g_QPCFrequenz);

end.
Anwendung:
Delphi-Quellcode:
var
  StopUhr : TStopUhr;
begin
  StopUhr := TStopUhr.Create;
  StopUhr.MeasureMethode := su_TickCount; // default = su_DateTime
  StopUhr.Start;

  // zu messende Aufgabe

  StopUhr.Stop;
  ShowMessage(StopUhr.StoppedTimeStr);
  StopUhr.Free;
end;
Die Eigenschaft MeasureMethode muss nicht gesetzt werden, wenn man die Messmethode nicht verändern will.

su_DateTime
Systemzeit-Vergleich, weshalb hier auch lange Zeiten recht genau bleiben.
su_TickCount
WindowsCounter, der pro Millisekunde hochzählt. Nach 42 Tagen stellt er auf 0, minimales Risiko der Fehlmessung. Bei einem gepflegten System ist das Risiko dank monatlicher Updates nahezu 0.
su_Performance
Verwendet den QueryPerformanceCounter, dessen Genauigkeit aber unter Windows auch nicht wirklich besser ist. Deshalb wird er wie alle anderen Mess-Methoden nur bis 1 ms Genauigkeit ausgewertet. Der QPC ist nicht immer verfügbar, konnte aber auf die schnelle nicht herausfinden, unter welchen Umständen.

€: kaum gepostet fällt mir ein, das man bei DateTime noch den Tag auswerten könnte... nachgebessert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf