【发布时间】:2012-02-18 23:13:09
【问题描述】:
我正在向 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 步 - 确保没有将列设置为 “auto-width”:
检查
-
第 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();
快了一个数量级。
我缺少 WinForms ListView 包装器的哪些属性?
【问题讨论】:
-
旁注:如果使用复选框,您应该在添加到 ListView 之前设置选中状态。初始化检查状态blogs.msdn.com/b/hippietim/archive/2006/03/20/556007.aspx
-
我不得不问:你为什么要添加这么多项目?
-
伊恩的好问题。你看过这个关于这个主题的博客吗? virtualdub.org/blog/pivot/entry.php?id=273
-
1,349 毫秒,不可能。我尝试使用 53709 个项目,这需要几分钟。为什么要使用包含这么多项目的列表视图? , 不是真的有用。您可以使用 listBox 或 comboBox 来提高速度,但这是一个疯狂的数字
-
为什么不使用虚拟列表视图?好的,您需要编程如何检索项目数据,并且您可能需要维护其他事情,例如排序、过滤等,但无论项目有多少,您都会立即填充列表视图。
标签: c# winforms performance listview