Tôi đang thêm một vài nghìn (ví dụ: 53,709) mục vào một ListView WinForms.Làm thế nào để tăng tốc độ thêm các mục vào một ListView?
Cố gắng 1: 13,870 ms
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
này chạy rất nặng. Sửa chữa đầu tiên rõ ràng là gọi BeginUpdate/EndUpdate
.
Cố gắng 2: 3,106 ms
listView.BeginUpdate();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
listView.EndUpdate();
này là tốt hơn, nhưng vẫn theo độ quá chậm. Hãy sáng tạo riêng của ListViewItems từ việc thêm ListViewItems, vì vậy chúng tôi tìm ra thủ phạm thực tế:
Nỗ lực 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()
Các nút cổ chai thực sẽ bổ sung các hạng mục. Hãy thử chuyển đổi nó để AddRange
chứ không phải là một Cố gắng foreach
4:2,182 ms
listView.BeginUpdate();
listView.Items.AddRange(items.ToArray());
listView.EndUpdate();
Một chút tốt hơn. Hãy chắc chắn rằng các nút cổ chai không nằm trong ToArray()
Nỗ lực 5:2,132 ms
ListViewItem[] arr = items.ToArray();
stopwatch.Start();
listView.BeginUpdate();
listView.Items.AddRange(arr);
listView.EndUpdate();
stopwatch.Stop();
Giới hạn dường như có thêm mục vào listview. Có lẽ sự quá tải khác của AddRange
, nơi chúng ta thêm một ListView.ListViewItemCollection
chứ không phải là một mảng
Cố 6:2,141 ms
listView.BeginUpdate();
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
lvic.AddRange(arr);
listView.EndUpdate();
Vâng đó là không tốt.
Bây giờ là lúc để căng:
Bước 1 - đảm bảo không có cột được thiết lập để "auto-width":
Kiểm tra
Bước 2 - đảm bảo ListView không cố gắng để sắp xếp các mục mỗi lần tôi thêm một:
Kiểm tra
Bước 3 - Hỏi stackoverflow:
Kiểm tra
Lưu ý: Rõ ràng ListView đây không phải là trong chế độ ảo; vì bạn không/không thể "thêm" các mục vào chế độ xem danh sách ảo (bạn đặt VirtualListSize
). May mắn thay câu hỏi của tôi không phải là về một cái nhìn danh sách trong chế độ ảo.
Có bất kỳ điều gì tôi thiếu mà có thể tính đến việc thêm các mục vào chế độ xem danh sách quá chậm?
Bonus nhí
tôi biết lớp ListView Windows có thể làm tốt hơn, bởi vì tôi có thể viết mã nào đó trong 394 ms
:
ListView1.Items.BeginUpdate;
for i := 1 to 53709 do
ListView1.Items.Add();
ListView1.Items.EndUpdate;
mà khi so sánh với tương đương với C# mã 1,349 ms
:
listView.BeginUpdate();
for (int i = 1; i <= 53709; i++)
listView.Items.Add(new ListViewItem());
listView.EndUpdate();
là thứ tự cường độ nhanh hơn.
Thuộc tính nào của trình bao bọc ListView WinForms am i bị thiếu?
Lưu ý phụ: Nếu sử dụng Hộp kiểm, bạn nên đặt trạng thái đã chọn trước khi thêm vào ListView. Đang khởi tạo các trạng thái đã chọn http://blogs.msdn.com/b/hippietim/archive/2006/03/20/556007.aspx –
Tôi phải hỏi: tại sao bạn lại thêm nhiều mục? –
Câu hỏi lớn Ian. Bạn đã xem blog này về chủ đề chưa? http://www.virtualdub.org/blog/pivot/entry.php?id=273 –