title: How to speed adding items to a ListView?
body: <p>i'm adding a few thousand (e.g. 53,709) items to a WinForms ListView.</p>
  
  <p><strong>Attempt 1</strong>: <code>13,870 ms</code></p>
  
  <pre><code>foreach (Object o in list)
  {
     ListViewItem item = new ListViewItem();
     RefreshListViewItem(item, o);
     listView.Items.Add(item);
  }
  </code></pre>
  
  <p>This runs very badly. The obvious first fix is to call <code>BeginUpdate/EndUpdate</code>.</p>
  
  <p><strong>Attempt 2</strong>: <code>3,106 ms</code></p>
  
  <pre><code>listView.BeginUpdate();
  foreach (Object o in list)
  {
     ListViewItem item = new ListViewItem();
     RefreshListViewItem(item, o);
     listView.Items.Add(item);
  }
  listView.EndUpdate();
  </code></pre>
  
  <p>This is better, but still an order of magnitude too slow. Let's separate creation of ListViewItems from adding ListViewItems, so we find the actual culprit:</p>
  
  <p><strong>Attempt 3</strong>: <code>2,631 ms</code></p>
  
  <pre><code>var items = new List&lt;ListViewItem&gt;();
  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()
  </code></pre>
  
  <p>The real bottleneck is adding the items. Let's try converting it to <code>AddRange</code> rather than a <code>foreach</code></p>
  
  <p><strong>Attempt 4:</strong> <code>2,182 ms</code></p>
  
  <pre><code>listView.BeginUpdate();
  listView.Items.AddRange(items.ToArray());
  listView.EndUpdate();
  </code></pre>
  
  <p>A bit better. Let's be sure that the bottleneck isn't in the <code>ToArray()</code></p>
  
  <p><strong>Attempt 5:</strong> <code>2,132 ms</code></p>
  
  <pre><code>ListViewItem[] arr = items.ToArray();
  
  stopwatch.Start();
  
  listView.BeginUpdate();
  listView.Items.AddRange(arr);
  listView.EndUpdate();
  
  stopwatch.Stop();
  </code></pre>
  
  <p>The limitation seems to be adding items to the listview. Maybe the other overload of <code>AddRange</code>, where we add a <code>ListView.ListViewItemCollection</code> rather than an array</p>
  
  <p><strong>Attempt 6:</strong> <code>2,141 ms</code></p>
  
  <pre><code>listView.BeginUpdate();
  ListView.ListViewItemCollection lvic = new ListView.ListViewItemCollection(listView);
  lvic.AddRange(arr);
  listView.EndUpdate();
  </code></pre>
  
  <p>Well that's no better.</p>
  
  <p>Now it's time to stretch:</p>
  
  <ul>
  <li><p><strong>Step 1</strong> - make sure no column is set to <em>"auto-width"</em>:</p>
  
  <p><img src="https://i.stack.imgur.com/Gs10n.png" alt="enter image description here"></p>
  
  <p><strong>Check</strong></p></li>
  <li><p><strong>Step 2</strong> - make sure the ListView isn't trying to sort the items each time i add one:</p>
  
  <p><img src="https://i.stack.imgur.com/Y371N.png" alt="enter image description here"></p>
  
  <p><strong>Check</strong></p></li>
  <li><p><strong>Step 3</strong> - Ask stackoverflow:</p>
  
  <p><img src="https://i.stack.imgur.com/PDQ5U.png" alt="enter image description here"></p>
  
  <p><strong>Check</strong></p></li>
  </ul>
  
  <p><strong>Note:</strong> Obviously this ListView is not in virtual mode; since you don't/cannot "add" items to a virtual list view (you set the <code>VirtualListSize</code>). Fortunately my question is not about a list view in virtual mode.</p>
  
  <p>Is there anything i am missing that might account for adding items to the listview being so slow?</p>
  
  <hr>
  
  <p><strong>Bonus Chatter</strong></p>
  
  <p>i know the Windows ListView class can do better, because i can write code that does it in <code>394 ms</code>:</p>
  
  <pre><code>ListView1.Items.BeginUpdate;
  for i := 1 to 53709 do
     ListView1.Items.Add();
  ListView1.Items.EndUpdate;
  </code></pre>
  
  <p>which when compared to the equivalent C# code <code>1,349 ms</code>:</p>
  
  <pre><code>listView.BeginUpdate();
  for (int i = 1; i &lt;= 53709; i++)
     listView.Items.Add(new ListViewItem());
  listView.EndUpdate();
  </code></pre>
  
  <p>is an order of magnitude faster.</p>
  
  <p>What property of the WinForms ListView wrapper am i missing?</p>