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 28. Jul 2025
Antwort Antwort
Seite 1 von 2  1 2      
m.pritscher

Registriert seit: 24. Jul 2025
5 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 14:17
Hallo zusammen,

wir beobachten in unserer Anwendung derzeit sehr lange Ladezeiten – insbesondere beim Befüllen von TComboBox-Elementen.
Das reine Hinzufügen von Strings dauert pro TComboBox etwa 0,5 Sekunden, was sich bei vielen Elementen massiv auf die Gesamtperformance auswirkt.

Zum Vergleich:
In einem separaten Testprogramm mit nahezu identischem Code (ebenfalls TComboBoxen, gleiche Datenbasis)
erfolgt das Befüllen deutlich schneller – nahezu ohne spürbare Verzögerung.

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.

Hat jemand eine Idee, woran diese extrem langen Ladezeiten liegen könnten?
Oder warum das Verhalten in der echten Anwendung so stark von einem einfachen Testprogramm abweicht?

Vielen Dank vorab für eure Hilfe!


Delphi-Quellcode:
// ------------------------- Hauptsoftware ------------------------- //
procedure TFenster_EinstInterfaces2.FormCreate(Sender: TObject);
begin
  LogProcedureStart('--- FormCreate ---');
  StartTime := Now;

  // Liste vorbereiten
  varList := TStringList.Create;
  LogTime('Create varList', StartTime);
  StartTime := Now;
  try
    for i := 1 to 500 do
      varList.Add('<Var ' + IntToStr(i) + '>');
    LogTime('Filled varList with 500 entries', StartTime);
    StartTime := Now;

    // Comboboxen-Array
    cmbArray[1] := cmb1; cmbArray[2] := cmb2;
    cmbArray[3] := cmb3; cmbArray[4] := cmb4;
    cmbArray[5] := cmb5; cmbArray[6] := cmb6;
    cmbArray[7] := cmb7; cmbArray[8] := cmb8;
    cmbArray[9] := cmb9; cmbArray[10] := cmb10;

    // Comboboxen befüllen mit Update-Block
    for i := 1 to 10 do
    begin
      cmbArray[i].Items.Assign(varList);
      LogTime('Assigned cmb' + IntToStr(i), StartTime);
      StartTime:= Now;
    end;

  finally
    varList.Free;
    LogTime('Freed varList', StartTime);
    StartTime := Now;
  end;

  LogProcedureEnd('--- FormCreate ---');
end; {FormCreate}


procedure TFenster_EinstInterfaces2.ClearParVarPanel;
begin
  LogProcedureStart('--- ClearParVarPanel ---');

  StepStartTime := Now;
  for i := 1 to 15 do
  begin
    LoopStartTime := Now;
    hcombo := TComboBox(FindComponent('cmb' + IntToStr(i)));
    LogTime('FindComponent für cmb' + IntToStr(i), LoopStartTime);

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

  LogProcedureEnd('--- ClearParVarPanel ---');
end; {ClearParVarPanel}
Delphi-Quellcode:
// ------------------------- Testprogramm ------------------------- //
procedure TForm1.FormCreate(Sender: TObject);
var
  VarList: TStringList;
  i, aos: Integer;
  StartStepTime: TDateTime;
  cmbArray: array[1..10] of TComboBox;
begin
  FProcedureStartTime := Now;

  // Anzahl an Strings festlegen
  aos:= 500;

  LogProcedureStart('--- FormCreat ---');
  StartStepTime := Now;

  VarList := TStringList.Create;
  try
    for i := 1 to aos do
      VarList.Add('<Var ' + IntToStr(i) + '>');
    LogTime('VarList gefüllt (' + IntToStr(aos) + ')', StartStepTime);
    StartStepTime := Now;

    // Combobox-Array vorbereiten
    cmbArray[1] := cmb1; cmbArray[2] := cmb2;
    cmbArray[3] := cmb3; cmbArray[4] := cmb4;
    cmbArray[5] := cmb5; cmbArray[6] := cmb6;
    cmbArray[7] := cmb7; cmbArray[8] := cmb8;
    cmbArray[9] := cmb9; cmbArray[10] := cmb10;
    LogTime('Comboboxen Pointer', StartStepTime);
    StartStepTime := Now;

    // Comboboxen befüllen mit StringList
    for i := 1 to 10 do
    begin
      cmbArray[i].Items.Assign(VarList);
      LogTime('Assigned cmb' + IntToStr(i) + ' mit ' + IntToStr(aos) + ' Strings', StartStepTime);
      StartStepTime := Now;
    end;

  finally
    VarList.Free;
    LogTime('Freed VarList', StartStepTime);
  end;

  LogProcedureEnd('--- FormCreate ---');
end; {FormCreate}
Miniaturansicht angehängter Grafiken
itemindex-hauptsoftware.png   tcombobox-hauptsoftware.png   tcombobox-testprogramm.jpg  
  Mit Zitat antworten Zitat
shebang

Registriert seit: 7. Feb 2020
151 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 15:02
In deinem ersten Log sieht man wunderbar, dass das Problem nur bei den ComboBoxen 1-10 auftritt und nicht bei 11-15. Was ist also der Unterschied zwischen den beiden Gruppen? Ich vermute, dass 1-10 irgendwelche Events verknüpft haben, die nicht triviale Dinge tun.
  Mit Zitat antworten Zitat
m.pritscher

Registriert seit: 24. Jul 2025
5 Beiträge
 
Delphi 10 Seattle Professional
 
#3

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 15:23
Hi shebang,

danke für die Anmerkung.
11-15 werden einfach nur nicht befüllt mit der Stringliste und bleiben quasi leer. Deshalb geht das setzen des ItemIndex auch so fix
  Mit Zitat antworten Zitat
AuronTLG

Registriert seit: 2. Mai 2018
Ort: Marburg
341 Beiträge
 
Delphi 12 Athens
 
#4

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 15:41
Ich muss gestehen, ich habe noch nie so viele Einträge in eine ComboBox gehauen, dass ich mir dabei Gedanken um die Geschwindigkeit machen musste.
Hattest du schonmal Items.BeginUpdate/EndUpate um das Assign der ComboBox.Items herum probiert? Bisher scheinst du das nur beim setzen des ItemIndex zu machen.
Bei optischen Komponenten hat das für gewöhnlich einen großen Einfluss auf die Geschwindigkeit, ich bin mir aber gerade nicht sicher, wie sich das Assign diesbezüglich verhält.
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.732 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 16:22
Gibt es da vielleicht einen OnChange-Event, der ausgelöst werden könnte? Vielleicht mal testweise alle Events abklemmen?
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 17:16
Wirklich SO viel dort anzeigen?

Erstmal BeginUpdate
Delphi-Quellcode:
varList.Items.BeginUpdate;
try
  varList.Items.Clear;
  for i := 1 to 500 do
    varList.Add('<Var ' + IntToStr(i) + '>');
finally
  varList.Items.EndUpdate;
end;
Oder "in einem Schwups" zuweisen.
Delphi-Quellcode:
for i := 1 to 500 do
  stringList.Add('<Var ' + IntToStr(i) + '>');

{ besser nicht, wenn es sehr viel ist ... die ComboBox wäre schnell, aber es wird unschön erst ein langer String gebaut, der dann wieder zerlegt und dann in die Items übergeben }
//varList.Items.Text := stringList.Text; // PS: die nutzen da drin auch BeginUpdate ;)

// oder
varList.Items.Clear;
varList.Items.AddStrings(stringList); // PS: die nutzen da drin auch BeginUpdate ;)
Delphi-Quellcode:
SetLength(arrList, 500);
for i := 1 to 500 do
  arrList[i - 1] := '<Var ' + IntToStr(i) + '>';
varList.Items.Clear;
varList.Items.AddStrings(arrList); // PS: die nutzen da drin auch BeginUpdate ;)



PS: Eine TComboBoxEx kann auch nachträglich befüllt werden.

Bei der TComboBox wird zu Beginn des OnDropDown eine Kopie im DropDown-Fenster geladen/angezeigt,
aber bei TComboBoxEx lässt sich während und auch nach dem Öffnen diese Liste noch bearbeiten.

Dort wäre es z.B. möglich erstmal nur einen Teil zu laden
und wenn der Fokus auf dem letzten Item steht, den Rest, bzw. den nächsten Teil zu laden.



Ich hab mal eine ComboBox gebaut, welche Ports auflistet. (hier war nicht die ComboBox selbst das Langsame, sondern die Datenquelle)
Die wird erst gefüllt/gesucht, wenn der DropDown auf geht. (also wenn nicht nötig, wird auch nicht gesucht)
Und wenn es bei der Suche hängt, dann ist schonmal der bereits gesuchte Teil angezeigt, weiteres taucht nach und nach auf. (die Suche läuft in Threads und beendet sich beim OnCloseUp)


Von DevExpress und Anderen gibt es ComboBoxen, welche einen Filter bieten,
also egal wie viele Zeilen/Datensätze es sind, da wird NIEMALS alles angezeigt. (kann also auch nicht langsam werden)
* z.B. nur die ersten 50
* und via Filter die Auswahl einschränken (davon auch nur die ersten 50)
* auch wenn nicht immer alles da ist, kommt man dennoch an jeden Eintrag dran
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (24. Jul 2025 um 17:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 24. Jul 2025, 22:43
Das Items.Assign verwendet intern auch schon ein BeginUpdate/EndUpdate und ruft darin ein Clear und AddStrings auf. Die Lösung mit Assign wird sich also im zeitlichen Rahmen der anderen Ansätze bewegen.

Die in dem Test erreichten 20 ms sind schon sehr gut und lassen sich wohl kaum merklich verbessern. Die Diskrepanz zu den 500ms im eigentlichen Programm kriegt man aber wohl nicht mit einer Optimierung des Befüll-Codes in den Griff. Da gilt es erstmal die eigentliche Ursache herauszufinden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.420 Beiträge
 
Delphi 12 Athens
 
#8

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 25. Jul 2025, 05:16
Vielleicht mal testweise alle Events abklemmen?
Das ist auch mein erster Gedanke, das reine Befüllen der TComboBox ist kein Problem, da passiert im Hintergrund nicht wirklich etwas. Ich vermute das Problem auch auf Eurer Seite - Du selbst hast mit dem Testprogramm schon bewiesen, dass es eigentlich kein Problem ist. Selbst wenn Du 100000 Einträge hättest, die Control stört sich daran nicht. Der Nutzer eher

......
Lizbeth W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
m.pritscher

Registriert seit: 24. Jul 2025
5 Beiträge
 
Delphi 10 Seattle Professional
 
#9

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 25. Jul 2025, 09:39
Danke schonmal für die ganzen Vorschläge.

Begin-End zusätzlich nochmal einzubauen haben wir schon probiert - ohne merkbare Verbesserung.
Auch Events sind keine gesetzt, die evtl. diese Ladezeiten erklären würden.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Performanceprobleme beim Befüllen von TComboBoxen

  Alt 25. Jul 2025, 10:50
Kannst du schrittweise den problematischen Code extrahieren, wobei durch hinzufügen und weg lassen der Auslöser eingegrenzt wird?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 04:03 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