tôi đang thêm một vài nghìn (ví dụ: 53,709) mục vào WinForms ListView.
Nỗ lực 1 :13,870 ms
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
Điều này chạy rất tệ. Cách khắc phục rõ ràng đầu tiên là gọi điện BeginUpdate/EndUpdate
.
Nỗ lực 2 :3,106 ms
listView.BeginUpdate();
foreach (Object o in list)
{
ListViewItem item = new ListViewItem();
RefreshListViewItem(item, o);
listView.Items.Add(item);
}
listView.EndUpdate();
Điều này tốt hơn, nhưng vẫn là một thứ tự cường độ quá chậm. Hãy tách việc tạo ListViewItems khỏi việc thêm ListViewItems, để chúng tôi tìm ra thủ phạm thực sự:
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()
Điểm nghẽn thực sự là thêm các mặt hàng. Chúng ta hãy cố gắng chuyển đổi nó sang AddRange
chứ không phải là mộtforeach
Nỗ lực 4: 2,182 ms
listView.BeginUpdate();
listView.Items.AddRange(items.ToArray());
listView.EndUpdate();
Tốt hơn một chút. Hãy chắc chắn rằng nút thắt cổ chai không nằm trongToArray()
Nỗ lực 5: 2,132 ms
ListViewItem[] arr = items.ToArray();
stopwatch.Start();
listView.BeginUpdate();
listView.Items.AddRange(arr);
listView.EndUpdate();
stopwatch.Stop();
Hạn chế dường như là thêm các mục vào chế độ xem danh sách. Có thể quá tải khác AddRange
, nơi chúng tôi thêm một ListView.ListViewItemCollection
thay vì một mảng
Nỗ lực 6: 2,141 ms
listView.BeginUpdate();
ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
lvic.AddRange(arr);
listView.EndUpdate();
Điều đó không tốt hơn.
Bây giờ là lúc để kéo dài:
Bước 1 - đảm bảo không có cột nào được đặt thành "chiều rộng tự động" :
Kiểm tra
Bước 2 - đảm bảo rằng ListView không cố gắng sắp xếp các mục mỗi khi tôi thêm một mục:
Kiểm tra
Bước 3 - Hỏi stackoverflow:
Kiểm tra
Lưu ý: Rõ ràng ListView này không ở 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 về chế độ xem danh sách ở chế độ ảo.
Có điều gì tôi còn thiếu có thể giải thích cho việc thêm các mục vào listview quá chậm không?
Bonus Chatter
tôi biết lớp ListView của Windows có thể làm tốt hơn, vì tôi có thể viết mã thực hiện nó 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 mã C # tương đương 1,349 ms
:
listView.BeginUpdate();
for (int i = 1; i <= 53709; i++)
listView.Items.Add(new ListViewItem());
listView.EndUpdate();
là một thứ tự của độ lớn nhanh hơn.
Tôi đang thiếu thuộc tính nào của trình bao bọc WinForms ListView?