Benutzer:Damadmax: Unterschied zwischen den Versionen
Aus DGL Wiki
(→Klassen) |
|||
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
+ | =Über mich= | ||
''BETRETEN DER BAUSTELLE AUF EIGENE GEFAHR!'' | ''BETRETEN DER BAUSTELLE AUF EIGENE GEFAHR!'' | ||
− | = | + | =Klassen= |
+ | Über die vergangene Zeit sind ein paar Klassen entstanden, die vielleicht für den ein oder anderen nützlich sein könnten. | ||
− | = Testanwendungen = | + | ==Klasse Timing== |
+ | Dies ist die Timing-Klasse wie ich sie in allen meiner Testprogramme und Projekte verwende. | ||
+ | <pascal>unit DETiming; | ||
+ | |||
+ | interface | ||
+ | |||
+ | type | ||
+ | TDETiming = class | ||
+ | public | ||
+ | constructor Create; | ||
+ | destructor Destroy; override; | ||
+ | procedure Init; | ||
+ | procedure Tick; | ||
+ | |||
+ | var | ||
+ | FrameTime : single; | ||
+ | FramesPerSecond : single; | ||
+ | FrameTimeInMs : single; | ||
+ | TotalFramesDrawn : int64; | ||
+ | CurrentFrames : integer; | ||
+ | TotalTimeRunning : single; | ||
+ | |||
+ | private var | ||
+ | QPCFreq : int64; | ||
+ | QPCLast : int64; | ||
+ | QPCNow : int64; | ||
+ | end; | ||
+ | |||
+ | implementation | ||
+ | |||
+ | uses | ||
+ | Windows; | ||
+ | |||
+ | constructor TDETiming.Create; | ||
+ | begin | ||
+ | inherited Create; | ||
+ | Init; | ||
+ | end; | ||
+ | |||
+ | destructor TDETiming.Destroy; | ||
+ | begin | ||
+ | inherited Destroy; | ||
+ | end; | ||
+ | |||
+ | procedure TDETiming.Init; | ||
+ | begin | ||
+ | QueryPerformanceCounter(QPCLast); | ||
+ | QueryPerformanceFrequency(QPCFreq); | ||
+ | CurrentFrames := 0; | ||
+ | TotalFramesDrawn := 0; | ||
+ | TotalTimeRunning := 0; | ||
+ | end; | ||
+ | |||
+ | procedure TDETiming.Tick; | ||
+ | begin | ||
+ | QueryPerformanceCounter(QPCNow); // PerfCounter abfragen | ||
+ | TotalFramesDrawn := TotalFramesDrawn + 1; // Selbsterklaerend :) | ||
+ | FrameTimeInMS := (QPCNow - QPCLast) / QPCFreq; // Zeit in Millisekunden pro Frame; fuer Timebased Movement | ||
+ | FrameTime := FrameTimeInMS * 1000.0; // Zeit in Sekunden | ||
+ | TotalTimeRunning := TotalTimeRunning + FrameTime; // Laufzeit in Sekunden | ||
+ | FramesPerSecond := 1.0 / FrameTimeInMs; // Frames pro Sekunde | ||
+ | QPCLast := QPCNow; // PerfCounter speichern | ||
+ | end;</pascal> | ||
+ | |||
+ | ==Klasse Profiler== | ||
+ | Den Profiler benutze ich um festzustellen wieviel Zeit in welchem Programmteil vergeht. | ||
+ | Nach jedem Programmabschnitt der untersucht werden soll die Funktion Add mit einem fortlaufenden Wert (0, 1, 2, ...) aufrufen. | ||
+ | Die Funktion AsString liefert die Werte in Prozent. | ||
+ | <pascal> | ||
+ | unit DEProfiler; | ||
+ | |||
+ | interface | ||
+ | |||
+ | type | ||
+ | TDEProfiler = class | ||
+ | public | ||
+ | constructor Create; overload; | ||
+ | constructor Create(AMeasureCount:word); overload; | ||
+ | destructor Destroy; override; | ||
+ | procedure Add(AIndex:word); | ||
+ | function GetSum: int64; | ||
+ | function GetValue(AIndex:word): int64; | ||
+ | function AsString : String; // Hilfsfunktion fuer Logausgabe (in %) | ||
+ | procedure Reset; | ||
+ | |||
+ | private | ||
+ | FLastAddTime : int64; | ||
+ | FSum : int64; | ||
+ | FMeasuredValues : Array of int64; | ||
+ | FSize : word; | ||
+ | |||
+ | procedure Init(ASize:word); | ||
+ | procedure ResetValues; | ||
+ | function CheckRange(AIndex:word): Boolean; | ||
+ | end; | ||
+ | |||
+ | implementation | ||
+ | |||
+ | uses | ||
+ | Windows, | ||
+ | SysUtils; | ||
+ | |||
+ | constructor TDEProfiler.Create; | ||
+ | begin | ||
+ | inherited Create; | ||
+ | Init(8); // Standardmaessig 8 Eintraege | ||
+ | end; | ||
+ | |||
+ | constructor TDEProfiler.Create(AMeasureCount:word); | ||
+ | begin | ||
+ | inherited Create; | ||
+ | Init(AMeasureCount); // Benutzerdefinierte Anzahl Eintraege | ||
+ | end; | ||
+ | |||
+ | destructor TDEProfiler.Destroy; | ||
+ | begin | ||
+ | inherited Destroy; | ||
+ | end; | ||
+ | |||
+ | procedure TDEProfiler.Add(AIndex:word); | ||
+ | var | ||
+ | ActTime : int64; | ||
+ | Diff : int64; | ||
+ | begin | ||
+ | QueryPerformanceCounter( ActTime ); | ||
+ | Diff := ActTime - FLastAddTime; | ||
+ | FMeasuredValues[AIndex] := FMeasuredValues[AIndex] + Diff; | ||
+ | FSum := FSum + Diff; | ||
+ | FLastAddTime := ActTime; | ||
+ | end; | ||
+ | |||
+ | function TDEProfiler.GetSum: int64; | ||
+ | begin | ||
+ | Result := FSum; | ||
+ | end; | ||
+ | |||
+ | function TDEProfiler.GetValue(AIndex:word): int64; | ||
+ | begin | ||
+ | if CheckRange(AIndex) then | ||
+ | Result := FMeasuredValues[AIndex] | ||
+ | else | ||
+ | Result := 0; | ||
+ | end; | ||
+ | |||
+ | procedure TDEProfiler.Reset; | ||
+ | begin | ||
+ | ResetValues; | ||
+ | end; | ||
+ | |||
+ | function TDEProfiler.AsString: String; | ||
+ | var | ||
+ | i : word; | ||
+ | begin | ||
+ | for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin | ||
+ | Result := Result + format(' / %d: %f', [ i, 100 / FSum * FMeasuredValues[i] ]); | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | procedure TDEProfiler.Init(ASize:word); | ||
+ | begin | ||
+ | FSize := ASize; | ||
+ | SetLength(FMeasuredValues, FSize); | ||
+ | QueryPerformanceCounter( FLastAddTime ); | ||
+ | ResetValues; | ||
+ | end; | ||
+ | |||
+ | procedure TDEProfiler.ResetValues; | ||
+ | var | ||
+ | i : word; | ||
+ | begin | ||
+ | for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin | ||
+ | FMeasuredValues[i] := 0; | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | function TDEProfiler.CheckRange(AIndex:word): Boolean; | ||
+ | begin | ||
+ | Result := (Low(FMeasuredValues) <= AIndex) and (High(FMeasuredValues) >= AIndex); | ||
+ | end; | ||
+ | |||
+ | end. | ||
+ | </pascal> | ||
+ | |||
+ | =Testanwendungen= | ||
Die ich in den vergangenen Monaten geschrieben habe. | Die ich in den vergangenen Monaten geschrieben habe. | ||
− | == Landschaft == | + | ==Landschaft== |
Aktuelle Version vom 1. Juli 2008, 00:49 Uhr
Inhaltsverzeichnis
Über mich
BETRETEN DER BAUSTELLE AUF EIGENE GEFAHR!
Klassen
Über die vergangene Zeit sind ein paar Klassen entstanden, die vielleicht für den ein oder anderen nützlich sein könnten.
Klasse Timing
Dies ist die Timing-Klasse wie ich sie in allen meiner Testprogramme und Projekte verwende.
unit DETiming; interface type TDETiming = class public constructor Create; destructor Destroy; override; procedure Init; procedure Tick; var FrameTime : single; FramesPerSecond : single; FrameTimeInMs : single; TotalFramesDrawn : int64; CurrentFrames : integer; TotalTimeRunning : single; private var QPCFreq : int64; QPCLast : int64; QPCNow : int64; end; implementation uses Windows; constructor TDETiming.Create; begin inherited Create; Init; end; destructor TDETiming.Destroy; begin inherited Destroy; end; procedure TDETiming.Init; begin QueryPerformanceCounter(QPCLast); QueryPerformanceFrequency(QPCFreq); CurrentFrames := 0; TotalFramesDrawn := 0; TotalTimeRunning := 0; end; procedure TDETiming.Tick; begin QueryPerformanceCounter(QPCNow); // PerfCounter abfragen TotalFramesDrawn := TotalFramesDrawn + 1; // Selbsterklaerend :) FrameTimeInMS := (QPCNow - QPCLast) / QPCFreq; // Zeit in Millisekunden pro Frame; fuer Timebased Movement FrameTime := FrameTimeInMS * 1000.0; // Zeit in Sekunden TotalTimeRunning := TotalTimeRunning + FrameTime; // Laufzeit in Sekunden FramesPerSecond := 1.0 / FrameTimeInMs; // Frames pro Sekunde QPCLast := QPCNow; // PerfCounter speichern end;
Klasse Profiler
Den Profiler benutze ich um festzustellen wieviel Zeit in welchem Programmteil vergeht. Nach jedem Programmabschnitt der untersucht werden soll die Funktion Add mit einem fortlaufenden Wert (0, 1, 2, ...) aufrufen. Die Funktion AsString liefert die Werte in Prozent.
unit DEProfiler; interface type TDEProfiler = class public constructor Create; overload; constructor Create(AMeasureCount:word); overload; destructor Destroy; override; procedure Add(AIndex:word); function GetSum: int64; function GetValue(AIndex:word): int64; function AsString : String; // Hilfsfunktion fuer Logausgabe (in %) procedure Reset; private FLastAddTime : int64; FSum : int64; FMeasuredValues : Array of int64; FSize : word; procedure Init(ASize:word); procedure ResetValues; function CheckRange(AIndex:word): Boolean; end; implementation uses Windows, SysUtils; constructor TDEProfiler.Create; begin inherited Create; Init(8); // Standardmaessig 8 Eintraege end; constructor TDEProfiler.Create(AMeasureCount:word); begin inherited Create; Init(AMeasureCount); // Benutzerdefinierte Anzahl Eintraege end; destructor TDEProfiler.Destroy; begin inherited Destroy; end; procedure TDEProfiler.Add(AIndex:word); var ActTime : int64; Diff : int64; begin QueryPerformanceCounter( ActTime ); Diff := ActTime - FLastAddTime; FMeasuredValues[AIndex] := FMeasuredValues[AIndex] + Diff; FSum := FSum + Diff; FLastAddTime := ActTime; end; function TDEProfiler.GetSum: int64; begin Result := FSum; end; function TDEProfiler.GetValue(AIndex:word): int64; begin if CheckRange(AIndex) then Result := FMeasuredValues[AIndex] else Result := 0; end; procedure TDEProfiler.Reset; begin ResetValues; end; function TDEProfiler.AsString: String; var i : word; begin for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin Result := Result + format(' / %d: %f', [ i, 100 / FSum * FMeasuredValues[i] ]); end; end; procedure TDEProfiler.Init(ASize:word); begin FSize := ASize; SetLength(FMeasuredValues, FSize); QueryPerformanceCounter( FLastAddTime ); ResetValues; end; procedure TDEProfiler.ResetValues; var i : word; begin for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin FMeasuredValues[i] := 0; end; end; function TDEProfiler.CheckRange(AIndex:word): Boolean; begin Result := (Low(FMeasuredValues) <= AIndex) and (High(FMeasuredValues) >= AIndex); end; end.
Testanwendungen
Die ich in den vergangenen Monaten geschrieben habe.