Benutzer:Damadmax: Unterschied zwischen den Versionen
Aus DGL Wiki
K (→Timing Klasse) |
(→Klassen) |
||
| Zeile 6: | Zeile 6: | ||
Über die vergangene Zeit sind ein paar Klassen entstanden, die vielleicht für den ein oder anderen nützlich sein könnten. | Ü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. | Dies ist die Timing-Klasse wie ich sie in allen meiner Testprogramme und Projekte verwende. | ||
| − | |||
| − | |||
<pascal>unit DETiming; | <pascal>unit DETiming; | ||
| Zeile 72: | Zeile 71: | ||
==Klasse Profiler== | ==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> | <pascal> | ||
unit DEProfiler; | unit DEProfiler; | ||
| Zeile 80: | Zeile 82: | ||
TDEProfiler = class | TDEProfiler = class | ||
public | public | ||
| − | constructor Create;overload; | + | constructor Create; overload; |
| − | constructor Create(AMeasureCount:word);overload; | + | constructor Create(AMeasureCount:word); overload; |
| + | destructor Destroy; override; | ||
procedure Add(AIndex:word); | procedure Add(AIndex:word); | ||
function GetSum: int64; | function GetSum: int64; | ||
function GetValue(AIndex:word): int64; | function GetValue(AIndex:word): int64; | ||
function AsString : String; // Hilfsfunktion fuer Logausgabe (in %) | function AsString : String; // Hilfsfunktion fuer Logausgabe (in %) | ||
| − | + | procedure Reset; | |
private | private | ||
| Zeile 95: | Zeile 98: | ||
procedure Init(ASize:word); | procedure Init(ASize:word); | ||
| + | procedure ResetValues; | ||
function CheckRange(AIndex:word): Boolean; | function CheckRange(AIndex:word): Boolean; | ||
end; | end; | ||
| Zeile 101: | Zeile 105: | ||
uses | uses | ||
| − | Windows; | + | Windows, |
| + | SysUtils; | ||
constructor TDEProfiler.Create; | constructor TDEProfiler.Create; | ||
begin | begin | ||
inherited Create; | inherited Create; | ||
| − | Init( | + | Init(8); // Standardmaessig 8 Eintraege |
end; | end; | ||
| Zeile 115: | Zeile 120: | ||
end; | end; | ||
| − | + | destructor TDEProfiler.Destroy; | |
begin | begin | ||
| − | + | inherited Destroy; | |
| − | |||
| − | |||
end; | end; | ||
| Zeile 147: | Zeile 150: | ||
end; | end; | ||
| − | + | procedure TDEProfiler.Reset; | |
begin | begin | ||
| − | + | ResetValues; | |
end; | end; | ||
function TDEProfiler.AsString: String; | function TDEProfiler.AsString: String; | ||
var | var | ||
| − | i : | + | i : word; |
begin | begin | ||
for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin | for i := Low(FMeasuredValues) to High(FMeasuredValues) do begin | ||
| Zeile 161: | Zeile 164: | ||
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 | begin | ||
| − | + | Result := (Low(FMeasuredValues) <= AIndex) and (High(FMeasuredValues) >= AIndex); | |
end; | end; | ||
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.