最佳答案
我在 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
)。幸运的是,我的问题与虚拟模式中的列表视图无关。
我是否遗漏了什么东西,可以解释为什么向列表视图添加条目的速度如此之慢?
额外的闲聊
我知道 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();
数量级更快。
我遗漏了 WinFormsListView 包装的哪个属性?