AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi Performanceprobleme beim Befüllen von TComboBoxen
Thema durchsuchen
Ansicht
Themen-Optionen

Performanceprobleme beim Befüllen von TComboBoxen

Ein Thema von m.pritscher · begonnen am 24. Jul 2025 · letzter Beitrag vom 31. Jul 2025
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.549 Beiträge
 
Delphi 12 Athens
 
#11

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 25. Jul 2025, 12:22
Auch Events sind keine gesetzt, die evtl. diese Ladezeiten erklären würden.
Skins, VCL-Hooks uvm.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.054 Beiträge
 
Delphi 12 Athens
 
#12

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 25. Jul 2025, 13:17
Zusätzlich fällt auf, dass auch einfache Operationen wie "ItemIndex := -1" auf diese TComboBoxen
ebenfalls mehrere hundert Millisekunden (ca. 400–500 ms) benötigen.
Das sollte sich doch relativ einfach finden lassen:
Diese Aktion in eine Schleife packen und mehrfach ausführen (also mit unterschiedlichen Indizes). Dann laufen lassen und immer wieder im Debugger anhalten und schauen, was das Programm gerade macht...

Ansonsten gibt es Profiler, mit denen du genau siehst, was da passiert.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
m.pritscher

Registriert seit: 24. Jul 2025
6 Beiträge
 
Delphi 10 Seattle Professional
 
#13

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 28. Jul 2025, 10:37
Auch Events sind keine gesetzt, die evtl. diese Ladezeiten erklären würden.
Skins, VCL-Hooks uvm.
Eine gute Idee, die im Team auf großen Anklang gestoßen ist.
Nach Überprüfung, mussten wir leider feststellen, das mit den Default-Windows Einstellungen gearbeitet wird.
  Mit Zitat antworten Zitat
m.pritscher

Registriert seit: 24. Jul 2025
6 Beiträge
 
Delphi 10 Seattle Professional
 
#14

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 28. Jul 2025, 10:41
Zusätzlich fällt auf, dass auch einfache Operationen wie "ItemIndex := -1" auf diese TComboBoxen
ebenfalls mehrere hundert Millisekunden (ca. 400–500 ms) benötigen.
Das sollte sich doch relativ einfach finden lassen:
Diese Aktion in eine Schleife packen und mehrfach ausführen (also mit unterschiedlichen Indizes). Dann laufen lassen und immer wieder im Debugger anhalten und schauen, was das Programm gerade macht...

Ansonsten gibt es Profiler, mit denen du genau siehst, was da passiert.

Beim detaillierten Überprüfen dieses Ansatzes sind wir auf den womöglich "wahren Übeltäter" gestoßen.
Der eigentliche Zeitfresser scheint das "WM_SETREDRAW" zu sein.

Delphi-Quellcode:
// ------------------------- Hauptsoftware ------------------------- //
procedure TFenster_EinstInterfaces2.ClearParVarPanel;
begin
  StartParVarTime := Now;
  LogProcedureStart('--- ClearParVarPanel ---');

  StartStepTime := Now;
  for i := 1 to 15 do
  begin
    hedit := TLabeledEdit(FindComponent('ledt' + IntToStr(i)));
    if hedit <> nil then
    begin
      hedit.Text := '';
      hedit.Hint := sDblClickForVar;
    end;
  end;
  LogTime('ledt-Schleife abgeschlossen', StartStepTime);

  StartStepTime := Now;
  // Redraw deaktivieren (WM_SETREDRAW False)
  for i := 1 to 15 do
  begin
    StartLoopTime := Now;
    hcombo := TComboBox(FindComponent('cmb' + IntToStr(i)));
    LogTime('FindComponent', StartLoopTime);
    if Assigned(hcombo) then
      SendMessage(hcombo.Handle, WM_SETREDRAW, WPARAM(False), 0);
    LogTime('SendMessage redraw', StartLoopTime);
  end;
  LogTime('WM_SETREDRAW false', StartStepTime);

  // Alle Index-Werte in Schleife setzen
  StartStepTime := Now;
  for i := 1 to 15 do
  begin
    hcombo := TComboBox(FindComponent('cmb' + IntToStr(i)));

    if hcombo <> nil then
    begin
      StartLoopTime := Now;
      hcombo.Items.BeginUpdate;
      try
        hcombo.ItemIndex := -1;
      finally
        hcombo.Items.EndUpdate;
      end;
      LogTime('ItemIndex für cmb' + IntToStr(i), StartLoopTime);
    end
    else
    begin
      LogTime('cmb' + IntToStr(i) + ' = nil', StartLoopTime);
    end;
  end;
  LogTime('cmb-Schleife abgeschlossen', StartStepTime);

  StartStepTime := Now;
  // Redraw reaktivieren und Controls invalidieren
  for i := 1 to 15 do
  begin
    hcombo := TComboBox(FindComponent('cmb' + IntToStr(i)));
    if Assigned(hcombo) then
    begin
      SendMessage(hcombo.Handle, WM_SETREDRAW, WPARAM(True), 0);
      RedrawWindow(hcombo.Handle, nil, 0, RDW_INVALIDATE or RDW_UPDATENOW or RDW_ALLCHILDREN);
    end;
  end;
  LogTime('WM_SETREDRAW true', StartStepTime);

  LogTime('ClearParVarPanel gesamt:', StartParVarTime);
  LogProcedureEnd('--- ClearParVarPanel ---');
end;
Miniaturansicht angehängter Grafiken
screenshot-2025-07-28-113449.png  
Angehängte Dateien
Dateityp: txt logfile - 28-07-2025_10-44-10.txt (4,6 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Zoot

Registriert seit: 30. Jan 2006
Ort: Hessen
116 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 30. Jul 2025, 09:58
Da fehlen einem die Worte.
  Mit Zitat antworten Zitat
m.pritscher

Registriert seit: 24. Jul 2025
6 Beiträge
 
Delphi 10 Seattle Professional
 
#16

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt Gestern, 11:29
Da fehlen einem die Worte.
Wie darf man das verstehen Zoot?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.756 Beiträge
 
Delphi 12 Athens
 
#17

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt Gestern, 11:50
Wie verhält sich der Code denn ohne das ganze WM_SETREDRAW, BeginUpdate/Endupdate und LogTime, wenn lediglich die Zeit für die gesamte Routine gemessen wird?

Nebenbei: Das WM_SETREDRAW kann nur dann Wirkung zeigen, wenn viele Änderungen an einem Control durchgeführt werden. Hier ist es bei jeder Combobox nur das Setzen des ItemIndex und dafür bringt das WM_SETREDRAW nur noch mehr Overhead mit. Man könnte es stattdessen auf das gesamte Form anwenden anstatt auf die einzelnen Controls.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.134 Beiträge
 
Delphi 2009 Professional
 
#18

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt Gestern, 12:34
Der Overhead von TStrings ist mir auch schon bei TListItem.SubItems aufgefallen. Ich habe dann TListItem abgeleitet und mit einem selbstgeschriebenen TStrings-Erben versehen. Das ganze läuft um mehrere Größenordnungen(!) schneller, aber SubItems[i] kann nur noch geschrieben und nicht mehr gelesen werden, da ich keinen Bedarf hatte, den Getter zu implementieren, der die Strings von Windows zurückholt. TComboBox hat bisher bei mir keine Probleme gemacht, aber ein gewisses anderes Control, das ich auch hier verdächtige. Ich wette daher hiermit 100 Delphi-Drachmen, dass es sich bei cmb1 bis cmb10 weder um TComboBox noch einen Erben davon handelt. Top, die Wette gilt.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#19

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt Gestern, 12:56
Hi,
Beim detaillierten Überprüfen dieses Ansatzes sind wir auf den womöglich "wahren Übeltäter" gestoßen.
Der eigentliche Zeitfresser scheint das "WM_SETREDRAW" zu sein.
That log makes no sense, it looks like it is missing the reason of its use.

See, you missing core things to isolate, clearly the culprit is your approach with
1) FindComponent ! that thing is slow as turtle, you are repeating it and measuring it again and again....
2) What are these numbers in the scope "[xxx ms]" these makes no sense and not accumulate to the time on the left !?
3) I am afraid that "LogTime" and "LogProcedureEnd" have also something to do with efficient logging.

suggestion :
1) One FindComponent in that code and put them in a list if you want, and also measure it to put it this to rest.
2) Slice that procedure "ClearParVarPanel" into pieces, just simplify it as much as you can, one loop is more than enough, so either make it multiple procedures/functions or reduce it to %30 of its current lines.
3) Use one : either "WM_SETREDRAW" or "BeginUpdate..EndUpdate" but not both, these are messages and they are the same.
Kas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 22:46 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