ListViewのアイテム登録を高速に

ListViewのアイテム登録は工夫しないと遅いです。
10000件のアイテム登録のサンプルを作ってみました。

Public Class Form1
    ''' <summary>
    ''' 普通にデータ登録
    ''' </summary>
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim item As ListViewItem
        Dim sw As Stopwatch = Stopwatch.StartNew

        ListView1.Items.Clear()

        For i As Integer = 1 To 10000
            item = ListView1.Items.Add(i.ToString("D6"))
            item.SubItems.Add("2")
            item.SubItems.Add("3")
        Next

        ListView1.EnsureVisible(ListView1.Items.Count - 1)

        sw.Stop()
        Console.WriteLine("Button1: " & sw.ElapsedMilliseconds & "ms")
    End Sub

    ''' <summary>
    ''' データ登録が終わるまで描画をストップ
    ''' </summary>
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim item As ListViewItem
        Dim sw As Stopwatch = Stopwatch.StartNew

        ListView1.BeginUpdate()
        ListView1.Items.Clear()

        For i As Integer = 1 To 10000
            item = ListView1.Items.Add(i.ToString("D6"))
            item.SubItems.Add("2")
            item.SubItems.Add("3")
        Next

        ListView1.EnsureVisible(ListView1.Items.Count - 1)
        ListView1.EndUpdate()

        sw.Stop()
        Console.WriteLine("Button2: " & sw.ElapsedMilliseconds & "ms")
    End Sub

    ''' <summary>
    ''' リストにデータを登録した後、リストビューにまとめて登録
    ''' </summary>
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim item As ListViewItem
        Dim items As New List(Of ListViewItem)
        Dim sw As Stopwatch = Stopwatch.StartNew

        ListView1.BeginUpdate()
        ListView1.Items.Clear()

        For i As Integer = 1 To 10000
            item = New ListViewItem(i.ToString("D6"))
            item.SubItems.Add("2")
            item.SubItems.Add("3")

            items.Add(item)
        Next

        ListView1.Items.AddRange(items.ToArray)
        ListView1.EnsureVisible(ListView1.Items.Count - 1)
        ListView1.EndUpdate()

        sw.Stop()
        Console.WriteLine("Button3: " & sw.ElapsedMilliseconds & "ms")
    End Sub
End Class

結果は…
Button1: 14,835ms
Button2: 3,698ms
Button3: 1,940ms
Button1: 15,506ms
Button2: 4,139ms
Button3: 1,960ms

Button3が一番早いです。
Button3のBeginUpdate、EndUpdateはなくてもあまり変わりません。

おまけ…登録スピードにはあまり影響しないですけど、サブアイテム登録のサンプルも置いときます。コーディングには好みがありますけどボクはこっちで登録してます。

            item.SubItems.AddRange(New String() {
                "2",
                "3"
            })

コメント