我要在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步-确保每次添加一个ListView时都不会尝试对项目进行排序:
检查一下
步骤3-询问stackoverflow:
检查一下
注意:显然,此ListView不在虚拟模式下;由于您不/不能将项目“添加”到虚拟列表视图(您可以将VirtualListSize
)。幸运的是,我的问题不是关于虚拟模式下的列表视图。
我有什么丢失的东西可能会导致向列表视图添加项目的速度如此之慢?
奖金Chat不休
我知道Windows ListView类可以做得更好,因为我可以编写代码来做到这一点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包装器的什么属性?