Einzelnen Beitrag anzeigen

Benmik

Registriert seit: 11. Apr 2009
557 Beiträge
 
Delphi 12 Athens
 
#17

AW: Performance: mein Programm trödelt!

  Alt 10. Jun 2020, 15:56
Ich bin schon ein bisschen baff, weil ich dauernd an meinen Routinen (Grafikverarbeitung) herumbastle und schaue, ob ich sie nicht ein bisschen schneller kriege. Ich nehme dazu schlicht und einfach GetTickCount , in den seltensten Fällen QueryPerformanceCounter , und ich dachte, alle anderen täten das auch.

Meine einfachste Messvorrichtung geht so:
Delphi-Quellcode:
procedure Zeit(var GTC:Cardinal;Anzeigen:Boolean = False);
begin
  If Anzeigen
    then Showmessage('Benötigte Zeit: ' + FormatFloat('0,',GetTickCount - GTC) + ' Millisekunden. ')
    else GTC := GetTickCount;
end;

procedure MachWas;
var GTC:Cardinal;
begin
  Zeit(GTC);
  Sleep(100);
  Zeit(GTC,True);
end;
Die aufgebohrte Fassung, mit der ich beliebig viele Verarbeitungen auf einen Schlag erwische, egal, wo sie sich befinden, geht so (habe allerdings erst kürzlich daran herumgebosselt, Bugs sind also möglich):
Delphi-Quellcode:
procedure Zeit(Titel:string;var Txt:string;var GTC:Cardinal;ZeitEnde:Boolean = False;Anzeigen:Boolean = False);
var AnzMsec:Cardinal;
const LZ5 = #32#32#32#32#32;
begin
  // Schluss aller Zeitmessungungen, Anzeige Ergebnis
  If Anzeigen then begin
    AnzMsec := GetTickCount - GTC;
    Txt := Txt + FormatFloat('0,',AnzMsec) + ' msec';
    Showmessage(Txt);
  // Endpunkt der aktuellen Zeitmessung ohne sofortigen Beginn der nächsten Zeitmessung
  end else if ZeitEnde then begin
    AnzMsec := GetTickCount - GTC;
    Txt := Txt + FormatFloat('0,',AnzMsec) + ' msec' + sLineBreak;
  // Endpunkt der aktuellen Zeitmessung mit sofortigem Beginn der nächsten Zeitmessung
  end else if EndsText(LZ5,Txt) then begin
    AnzMsec := GetTickCount - GTC;
    Txt := Txt + FormatFloat('0,',AnzMsec) + ' msec' + sLineBreak;
    Txt := Txt + Titel + ': ' + LZ5;
    GTC := GetTickCount;
  // Beginn der allerersten Zeitmessung oder Aufruf einer neuen Zeitmessung ohne andere Messung unmittelbar davor
  end else if (Txt = '') or EndsText(sLineBreak,Txt) then begin
    Txt := Txt + Titel + ': ' + LZ5;
    GTC := GetTickCount;
  end else begin
    Showmessage('Fehler bei der Anordnung der Aufrufe.');
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var GTC:Cardinal; Txt:string;
begin
  Zeit('procedure Zeitfresser1',Txt,GTC);
  Sleep(100);
  Zeit('procedure Zeitfresser2',Txt,GTC);
  Sleep(200);
  Zeit('',Txt,GTC,True);
  // Andere Verarbeitungen
  Zeit('procedure Zeitfresser3',Txt,GTC);
  Sleep(300);
  Zeit('',Txt,GTC,False,True);
  Application.Terminate;
end;
Während der Entwicklungszeit (also ein paar Jahre lang...) benutze ich globale Variablen für GTC und Txt, damit ich sie nicht immer deklarieren muss.

Geändert von Benmik (10. Jun 2020 um 17:52 Uhr) Grund: sLineBreak, damit Sherlock friedlich ist
  Mit Zitat antworten Zitat