C # ListView.Items [i] .remove is very slow

This is my first time here, and I'm struggling to solve this problem. I have this piece of code:

try { progressBar1.Maximum = lista.Items.Count; lista.BeginUpdate(); for (int i = 0; lista.Items.Count > i; i++) //for (int i = lista.Items.Count - 1; -1 < i; i--) { if (lista.Items[i].SubItems[1].Text.ToLower().Contains(Text) == false) { lista.Items[i].Remove(); } progressBar1.Value = progressBar1.Value + 1; } lista.EndUpdate(); progressBar1.Value = 0; } catch (Exception errore) { txt_info.Text = "" + errore.Message; progressBar1.Value = 0; } 

The lista.items[i].remove extremely slow. lista is a ListView , and I'm working on a log file larger than 50,000 lines. Is there a way to speed up the process?

+6
source share
4 answers
 ListViewItem[] allElements = new ListViewItem[listView1.Items.Count]; listView1.Items.CopyTo(allElements, 0); List < ListViewItem > list = allElements.ToList(); list.RemoveAll(item => item.SubItems[1].Text.ToLower().Contains(TextToFind) == false); listView1.BeginUpdate(); listView1.Clear(); listView1.Items.AddRange(list.ToArray()); listView1.EndUpdate(); 

The first rule is never updated in a for loop. Your logic will only work up to half the list. I think this is not what you want.
I saw that manipulating listview.items is very slow even after using BeginUpdate and EndUpdate. The key is to do external manipulation (in the list or so), and then re-populate the list with AddRange (which is much faster than Add).

+1
source

I would use a different approach and use LINQ, something like this:

 lista.Items = lista.Items.Where(x=>x.SubItems[1].Text.ToLower.Contains(Text)).AsParallel().ToList(); 

Basically, rebuilding the list once rather than trying to delete individual items over and over.

+3
source

The easiest option is to use the RemoveAll method list .

list.RemoveAll(x => !x.SubItems[1].Text.ToLower().Contains(Text))

PS

You may want to find the speed increase in the actual comparison. Using String.Compare is much faster if your requirement fits. If you want to check for a substring, I would suggest using ToUpperInvariant for invariance-related issues - which was developed faster .

+3
source

You could paste it into a background worker and make it do it yourself. Therefore, your users can still use the program during this process.

0
source

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


All Articles