Friday, September 5, 2008

The fastest way to fill ListView control

Filling ListView control with Add method in VB.NET is fast enough when you are dealing with only a few items. Things get different when you have to insert hundreds or maybe a few thousands items to ListView control. In this case the user may experience a noticeable delay in the application.

The solution is to use AddRange method which is the fastest way to fill ListView control. Below is the comparison of these two methods.

Fill ListView control with Add method

The sample code uses ListView control in Details-mode with one column. The loop inserts 10 000 items to control. Timing method is simple and it is not meant to provide neither totally exact nor precise timing.

''' <summary>
''' Fill listview with Add method
''' </summary>
''' <param name="ListView1">ListView object</param>
''' <remarks></remarks>
Public Sub FillListViewWithAdd(ByRef ListView1 As ListView)
 '
 Dim StartTime As DateTime
 Dim Elapsed As Double
 Dim TempStr() As String
 Dim TempNode As ListViewItem
 Dim i As Integer

 ListView1.View = View.Details
 ListView1.Columns.Clear()
 ListView1.Columns.Add("Name", 180)
 ListView1.Items.Clear()

 ReDim TempStr(0)
 StartTime = System.DateTime.Now
 For i = 0 To 9999
   TempStr(0) = "Name" & i.ToString
   TempNode = New ListViewItem(TempStr)
   TempNode.Tag = i.ToString
   ListView1.Items.Add(TempNode)
 Next i
 Elapsed = System.DateTime.Now.Subtract(StartTime).TotalMilliseconds
 MessageBox.Show("Elapsed time " & Elapsed.ToString & " ms with ListView.Add", _
   "Elapsed Time", _
   MessageBoxButtons.OK, _
   MessageBoxIcon.Information)

End Sub

And the result is:

Timing of ListView.Add method

Fill ListView control with AddRange method

The sample code is basically same as above. Only differences are storing first ListViewItems to array and after that using AddRange method to insert items to ListView control.

''' <summary>
''' Fill listview with AddRange method
''' </summary>
''' <param name="ListView1">ListView object</param>
''' <remarks></remarks>
Public Sub FillListViewWithAddRange(ByRef ListView1 As ListView)
 '
 Dim StartTime As DateTime
 Dim Elapsed As Double
 Dim TempStr() As String
 Dim TempNode As ListViewItem
 Dim TempArr() As ListViewItem
 Dim i As Integer

 ListView1.View = View.Details
 ListView1.Columns.Clear()
 ListView1.Columns.Add("Name", 180)
 ListView1.Items.Clear()

 ReDim TempStr(0)
 ReDim TempArr(9999)
 StartTime = System.DateTime.Now
 For i = 0 To 9999
   TempStr(0) = "Name" & i.ToString
   TempNode = New ListViewItem(TempStr)
   TempNode.Tag = i.ToString
   TempArr(i) = TempNode
 Next i
 ListView1.Items.AddRange(TempArr)
 Elapsed = System.DateTime.Now.Subtract(StartTime).TotalMilliseconds
 MessageBox.Show("Elapsed time " & Elapsed.ToString & " ms with ListView.AddRange", _
   "Elapsed Time", _
   MessageBoxButtons.OK, _
   MessageBoxIcon.Information)

End Sub

And the result is:

Timing of ListView.AddRange method

Add method versus AddRange method

The conclusion is very clear. AddRange method offers the fastest way to fill ListView control. In the sample codes above the AddRange method was five times faster compared to Add method. This does not make Add method obsolete by any means. When you are dealing with only a few or a few hundreds of items, you may well use Add method.

4 comments:

hachre said...

Rather than using System.DateTime.Now you can use Stopwatch to track performance.

It is more accurate and directly provides the time required between Stopwatch.Start() and Stopwatch.Stop().

Teme64 said...

Thanks. Stopwatch class can be found in System.Diagnostics namespace in .NET 2.0 and later.

Jose said...

Thanx sooooooooooooooo much!!
GREAT!

Anonymous said...

Excellent find! This is probably due to the sorting involved - it is faster to do it in one shot.