Ich füge ein paar tausend (zB 53.709) Elemente zu einer WinForms ListView hinzu.
Versuch 1 :13,870 ms
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
Das läuft sehr schlecht. Die naheliegende erste Lösung besteht darin, anzurufen BeginUpdate/EndUpdate
.
Versuch 2 :3,106 ms
listView.BeginUpdate();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
listView.EndUpdate();
Das ist besser, aber immer noch eine Größenordnung zu langsam. Lassen Sie uns die Erstellung von ListViewItems vom Hinzufügen von ListViewItems trennen, damit wir den tatsächlichen Schuldigen finden:
Versuch 3 :2,631 ms
var items = new List<ListViewItem>();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
items.Add(item);
}
stopwatch.Start();
listView.BeginUpdate();
foreach (ListViewItem item in items)
listView.Items.Add(item));
listView.EndUpdate();
stopwatch.Stop()
Der eigentliche Engpass ist das Hinzufügen der Elemente. Versuchen wir, es in a AddRange
anstatt in a zu konvertierenforeach
Versuch 4: 2,182 ms
listView.BeginUpdate();
listView.Items.AddRange(items.ToArray());
listView.EndUpdate();
Ein bisschen besser. Stellen wir sicher, dass der Engpass nicht in derToArray()
Versuch 5: 2,132 ms
ListViewItem[] arr = items.ToArray();
stopwatch.Start();
listView.BeginUpdate();
listView.Items.AddRange(arr);
listView.EndUpdate();
stopwatch.Stop();
Die Einschränkung scheint darin zu bestehen, der Listenansicht Elemente hinzuzufügen. Vielleicht die andere Überladung von AddRange
, bei der wir ListView.ListViewItemCollection
eher ein als ein Array hinzufügen
Versuch 6: 2,141 ms
listView.BeginUpdate();
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
lvic.AddRange(arr);
listView.EndUpdate();
Nun, das ist nicht besser.
Jetzt ist es Zeit sich zu strecken:
Schritt 1 - Stellen Sie sicher, dass keine Spalte auf "automatische Breite" eingestellt ist :
Prüfen
Schritt 2 - Stellen Sie sicher, dass ListView nicht jedes Mal, wenn ich eines hinzufüge, versucht, die Elemente zu sortieren:
Prüfen
Schritt 3 - Stackoverflow fragen:
Prüfen
Hinweis: Diese ListView befindet sich offensichtlich nicht im virtuellen Modus. da Sie einer virtuellen Listenansicht keine Elemente hinzufügen können / können (Sie legen die fest VirtualListSize
). Zum Glück geht es bei meiner Frage nicht um eine Listenansicht im virtuellen Modus.
Fehlt mir etwas, das dafür verantwortlich sein könnte, dass das Hinzufügen von Elementen zur Listenansicht so langsam ist?
Bonus Chatter
Ich weiß, dass die Windows ListView-Klasse es besser kann, weil ich Code schreiben kann, der dies tut 394 ms
:
ListView1.Items.BeginUpdate;
for i := 1 to 53709 do
ListView1.Items.Add();
ListView1.Items.EndUpdate;
was im Vergleich zum entsprechenden C # -Code 1,349 ms
:
listView.BeginUpdate();
for (int i = 1; i <= 53709; i++)
listView.Items.Add(new ListViewItem());
listView.EndUpdate();
ist eine Größenordnung schneller.
Welche Eigenschaft des WinForms ListView-Wrappers fehlt mir?