AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delay zu langsam?

Ein Thema von Schorschi5566 · begonnen am 17. Jun 2010 · letzter Beitrag vom 17. Jun 2010
Antwort Antwort
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#1

AW: Delay zu langsam?

  Alt 17. Jun 2010, 19:36
Hallo Hagen,

vielen Dank für Deine ausführlichen Antworten.

Der Test war an sich schon richtig. Ich habe also natürlich nicht Application.ProcessMessages dringelassen, als Delay(10) aktiv war.

Ab Delay(50) ist auch alles in Ordnung. Nur darunter verbrät der Code mit Delay und reichlich Mausbewegung eben deutlich mehr Zeit.

Bei Delay(5000) sind es recht genau 5000ms, so wie das sein soll.

Mir war nur nicht bewußt, dass es ab der "Schwelle" 50ms zwischen Sleep mit App.Proc. und Delay ohne App.Proc. einen recht deutlichen Unterschied gibt, was das Zeitverhalten angeht.

Das hat auch nur den Hintergrund, dass ich im Moment einen Timer brauche, den ich damit getestet habe. Ist mir halt als Nebenprodukt aufgefallen und ich dachte mir, dass ich mal frage.


Zitat von Hagen:
Davon mal abgesehen halte ich generell nichts von einem Delay()
Na ja, einen Service lege ich schon ganz gerne mal mit Delay schlafen, ehe er ständig etwas berechnet, was man so oft eben nicht braucht. Ansonsten kann's mir eigentlich nicht schnell genug gehen.



Viele Grüße,
Uwe
Uwe
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Delay zu langsam?

  Alt 17. Jun 2010, 19:46
Gerade nochmal so getestet...

Delphi-Quellcode:
procedure TForm1.Test;
var
  I: Integer;
  T: cardinal;
begin
  // immer schön mit der Maus rühren...
  T := GetTickCount;
  // Schleife dauert ca. 5000ms.
  for I := 0 to 499 do
  begin
    Sleep(10);
    Application.ProcessMessages;
  end;
  T := GetTickCount - T;
  ShowMessage('Dein Delay = ' + IntToStr(T) + 'ms');

  T := GetTickCount;
  // Schleife dauert 7660ms.
  for I := 0 to 499 do
  begin
    Delay(10);
  end;
  T := GetTickCount - T;
  ShowMessage('Ungeschickter Delay = ' + IntToStr(T) + 'ms');

  T := GetTickCount;
  // Delay(5000) dauert ca. 5000ms.
  Delay(5000);
  T := GetTickCount - T;
  ShowMessage('Sinnvoller Delay = ' + IntToStr(T) + 'ms');
end;
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#3

AW: Delay zu langsam?

  Alt 17. Jun 2010, 20:18
Ja das sind so Sachen die passieren wenn man solche Tests auf einem System macht das im Grunde unberechenbar ist. Zb. deine zweite Schleife liefert auf den ersten Blick erstaunliche und wenig verständliche Resultate. Wenn man aber weiß was der Aufruf von Sleep() bedeutet wird das dann klarer. Sleep(0) zb. ist ein sinnvoller Aufruf auch wenn der aktuelle Thread keine 0 Millisekunden schlafen kann. Denn Sleep() führt in jedem Fall einen Task Wechsel aus. Dh. man übergibt programmatisch die Kontrolle an den taskscheduller vom OS und der wird einen Taskwechsel zu einem anderen Task durchführen. Nun entfernst du aber in der 2. Schleife nicht per .ProcessMessages die Nachrichten im Messagequeue und der läuft quasi voll. Das OS scheint nun dafür immer mehr Resourcen zu benötigen, zb. für die Verwaltung dieser Nachrichten und schwups wird der komplette Prozess ausgebremmst.

Durch den Overhead der zusätzlichen API Funktionen in meinem Delay() wird es ebenfalls zu einer Verschlechterung der Perfomance kommen, je kürzer die Wartezeit wird.

Zudem ist das Application.ProcessMessages ebenfalls eine "Störquelle". Diese Funktion kehrt abhängig von der Messageabarbeitung zurück. Es könnte also zb. Nachrichten geben die in einer Schleife enden. Zb. viele der Nachrichten für den Non Client Bereich von Fenstern verzweigen intern in Schleifen und geben die Kontrolle an den Aufrufer erst zurück wenn sie es wollen. Klicke und Ziehe zb. mal in den Fensterrahmen und lass die Maustaste gedrückt. Intern wird in eine Schleife verzweigt, im Windowskernel, die erst bei Loslassen der Maus zurückkehrt.

Deswegen, und noch vielen anderen Nachteilen, würde ich auf den Aufruf von Applikation.processMesages im eigenen Source oder Komponenten etc.pp. absolut verzichten. Ebenso wie ein Delay() um auf irgendwas zu warten. Das sind alles "Tricks" die kontraproduktiv sind. Kontraproduktiv weil es auch anders und weit besser geht. Zb. einen Timer per Messages oder Callback Funktion zu benutzen oder mit den Events des OS arbeiten, zb. bei fast allen Kommunikationsschnittstellen ist das möglich. Im schlechtesten Fall muß man eben einen Thread abspalten und kann in diesem ohne Messagequeue und Sleep() und Events sicher arbeiten. Man stellt also in jedem Fall das System auf Events um statt zu Pollen.

Gruß Hagen
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#4

AW: Delay zu langsam?

  Alt 17. Jun 2010, 20:39
Hallo Hagen,

Zitat von Hagen:
Nun entfernst du aber in der 2. Schleife nicht per .ProcessMessages die Nachrichten im Messagequeue und der läuft quasi voll.
Nö. Macht doch Dein Delay.

Delphi-Quellcode:
procedure Delay(Milliseconds: integer);
var
  Tick: DWORD;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWORD(Milliseconds);
    while (Milliseconds > 0) and (MsgWaitForMultipleObjects(1, Event, False,
        Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages; // <-- das ist er doch...der Aufruf!
      if Application.Terminated then Exit;
      Milliseconds := Tick - GetTickCount;
    end;
  finally
    CloseHandle(Event);
  end;
end;
Zitat von Hagen:
Durch den Overhead der zusätzlichen API Funktionen in meinem Delay() wird es ebenfalls zu einer Verschlechterung der Perfomance kommen, je kürzer die Wartezeit wird.
Ja, das auch, aber das erklärt nicht, warum die Schleife mit Delay(10) ohne Mausrühren exakt 5000ms braucht.

Scheint mir eher so, dass
Delphi-Quellcode:
MsgWaitForMultipleObjects(1, Event, False,
        Milliseconds, QS_ALLINPUT
wesentlich mehr Zeit als Milliseconds verbraucht, wenn die Funktion erstmal ausgeführt wird und Milliseconds < 50ms ist. Da liegt der Hase im Pfeffer und die Beschreibung der API-Funktion sollte vielleicht lauten, dass die Funktion wenigstens 50ms verbrät, wenn eine Message vorliegt.

Und damit wartet Delay < 50ms eben länger als erwartet, wenn viel los ist. Nicht mehr und nicht weniger.


Viele Grüße,
Uwe
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#5

AW: Delay zu langsam?

  Alt 17. Jun 2010, 21:04
Jo wäre auch eine Erklärung, aber ohne den Source dieser Funktionen ist das Raten

gruß Hagen
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#6

AW: Delay zu langsam?

  Alt 17. Jun 2010, 21:20
Na ja, was soll die Funktion schon machen, wenn eine Message vorliegt?

Sie wird sie halt abarbeiten und dabei sicherlich nicht ständig auf die Uhr schauen.

Eventuell sollte man bei Milliseconds < 50 einfach den Aufruf von MsgWaitForMultipleObjects weglassen dann würde es immerhin zeitlich bis runter zu 10ms passen.

Grüße,
Uwe
Uwe
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz