How to speed up the removal of ListView items ListViews?

I already use listView.BeginUpdate() and listView.EndUpdate() , but it still takes 10 seconds when I delete, for example, 100 items from 25k.

Any ideas, tricks to make it faster?

EDIT:

 this.listView.BeginUpdate(); for (int i = this.listView.CheckedItems.Count - 1; i > -1; --i) { this.listView.CheckedItems[i].Remove(); } this.listView.EndUpdate(); 
+4
source share
3 answers

You can start your optimization here:

 List<int> toRemove = new List<int>(); foreach (ListViewItem item in this.listView.Items) { if (item.Checked) // check other remove conditions here toRemove.Add(item.Index); } /* sort indices descending, so you'll remove items with higher indices first and they will not be shifted when you remove items with lower indices */ toRemove.Sort((x, y) => y.CompareTo(x)); /* in this specific case you can simply use toRemove.Reverse(); or iterate thru toRemove in reverse order because it is already sorted ascending. But you might want to force sort it descending in some other cases. */ this.listView.BeginUpdate(); foreach (int itemIndex in toRemove) this.listView.Items.RemoveAt(itemIndex); // use RemoveAt when possible. It much faster with large collections this.listView.EndUpdate(); 
+3
source

The ListView fires an event for each individual item that is removed from the list. You can try to avoid this by clearing the entire ListView, and then adding immediately a new list of items that lacks the 100 items you want to remove. This will trigger only a few events.

0
source

This is because every time you delete an item from Items, the ListView must find that item ( going through the list for this ) and update the CheckedItems collection (which repeats all the other items again), so the complexity is O ^ 2.

The easiest way is to cache SelectedIndices and use listItem.Items.RemoveAt ():

 var selectedIndices = listView.SelectedIndices.Cast<int>().Reverse().ToList(); listView.BeginUpdate(); foreach (var index in selectedIndices) { listView.Items.RemoveAt(index); } listView.EndUpdate(); 

If you do not want to use the Cast <> extension method, you can replace the first line:

 List<int> oToDelete = new List<int>(SelectedIndices.Count); foreach (int iX in SelectedIndices) { oToDelete.Add(iX); } oToDelete.Reverse(); 
0
source

Source: https://habr.com/ru/post/1439064/


All Articles