WinForms ListViewに数千(例:53,709)のアイテムを追加しています。
試行1:13,870 ms
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
これは非常にうまくいきません。明らかな最初の修正は、を呼び出すことBeginUpdate/EndUpdate
です。
試行2:3,106 ms
listView.BeginUpdate();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
listView.EndUpdate();
これは優れていますが、それでも桁違いに遅すぎます。ListViewItemsの作成とListViewItemsの追加を分けて、実際の原因を見つけましょう。
試行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()
本当のボトルネックは、アイテムの追加です。AddRange
ではなくに変換してみましょうforeach
試行4: 2,182 ms
listView.BeginUpdate();
listView.Items.AddRange(items.ToArray());
listView.EndUpdate();
少し良く。ボトルネックがないことを確認しましょうToArray()
試行5: 2,132 ms
ListViewItem[] arr = items.ToArray();
stopwatch.Start();
listView.BeginUpdate();
listView.Items.AddRange(arr);
listView.EndUpdate();
stopwatch.Stop();
制限は、リストビューにアイテムを追加することのようです。たぶん、配列ではなくAddRange
を追加する、の他のオーバーロードListView.ListViewItemCollection
試行6: 2,141 ms
listView.BeginUpdate();
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
lvic.AddRange(arr);
listView.EndUpdate();
まあそれは良くない。
さあ、ストレッチしましょう。
手順1- 「自動幅」に列が設定されていないことを確認します。
小切手
ステップ2-リストビューがアイテムを追加するたびにアイテムを並べ替えようとしていないことを確認します。
小切手
ステップ3-スタックオーバーフローを尋ねる:
小切手
注:明らかに、このListViewは仮想モードではありません。アイテムを仮想リストビューに「追加」できない/できないため(を設定しますVirtualListSize
)。幸い、私の質問は仮想モードでのリストビューに関するものではありません。
リストビューへのアイテムの追加が非常に遅い原因となる可能性のある、不足しているものはありますか?
ボーナスチャター
私はそれを行うコードを書くことができるので、WindowsListViewクラスがより良くできることを知っています394 ms
:
ListView1.Items.BeginUpdate;
for i := 1 to 53709 do
ListView1.Items.Add();
ListView1.Items.EndUpdate;
同等のC#コードと比較した場合1,349 ms
:
listView.BeginUpdate();
for (int i = 1; i <= 53709; i++)
listView.Items.Add(new ListViewItem());
listView.EndUpdate();
桁違いに高速です。
WinForms ListViewラッパーのどのプロパティがありませんか?