misc.log

日常茶飯事とお仕事と

CollectionとArrayListの速度比較

上記の時間計測に関するTipsは、実はCollectionを使ったデータ格納/検索と、ArrayListを使った場合の速度の違いを調べようとしていた副産物。キーを持たないデータなので、Collectionを使う必要は全く無い(というか、キーが事前に用意されていないデータしか無いので、Collectionの強みであるキーによる検索が使えない)。そのため、ArrayListでもいいんじゃないか、というのが今回の検証の動機。

まずはAddメソッドの処理速度を見る。

    Private Sub Prepare()

        Dim testCol As New Collection
        Dim testArray As New ArrayList

        Dim startTime, endtime As Date

        Trace.WriteLine("COLLECTION ADD")
        startTime = Now
        For i As Integer = 1 To 10000
            testCol.Add(i.ToString)
        Next
        endTime = Now
        Trace.WriteLine("START: " & Format(startTime, "hh:mm:ss:fff"))
        Trace.WriteLine("  END: " & Format(endTime, "hh:mm:ss:fff"))

        Trace.WriteLine("ARRAYLIST ADD")
        startTime = Now
        For i As Integer = 1 To 10000
            testArray.Add(i.ToString)
        Next
        endTime = Now
        Trace.WriteLine("START: " & Format(startTime, "hh:mm:ss:fff"))
        Trace.WriteLine("  END: " & Format(endTime, "hh:mm:ss:fff"))

    End Sub

結果は、

COLLECTION ADD
START: 11:50:05:046
  END: 11:50:05:062
ARRAYLIST ADD
START: 11:50:05:062
  END: 11:50:05:078

変わらない。だいたいどちらも16ミリセカンド。
次に、そこからFor Eachで1件ずつ比較して、条件に一致する情報を取り出すテストを行ってみる。For Eachなのでどの順に取り出すかがフレームワーク任せ(実際は決まっているのだろうけど)というのはあるが、何度か試せば傾向は見えるだろう。

    Private Sub PrepareArray()

        Dim startTime, endtime As Date

        Trace.WriteLine("ARRAYLIST ADD")
        startTime = Now
        For i As Integer = 1 To 10000
            testArray.Add(i.ToString)
        Next
        endtime = Now
        Trace.WriteLine("START: " & Format(startTime, "hh:mm:ss:fff"))
        Trace.WriteLine("  END: " & Format(endtime, "hh:mm:ss:fff"))

    End Sub

    Private Sub SearchTestArray()

        Dim startTime, endtime As Date

        Trace.WriteLine("ARRAYLIST SEARCH")
        startTime = Now
        For Each obj As Object In testArray
            If CType(obj, Integer) = 8000 Then
                Exit For
            End If
        Next
        endtime = Now
        Trace.WriteLine("START: " & Format(startTime, "hh:mm:ss:fff"))
        Trace.WriteLine("  END: " & Format(endtime, "hh:mm:ss:fff"))

    End Sub

上記のSubを連続して呼出し、時間をみてみた。上記はArrayListの例。

COLLECTION ADD
START: 01:31:02:953
  END: 01:31:02:968
COLLECTION SEARCH
START: 01:31:02:968
  END: 01:31:03:828

ARRAYLIST ADD
START: 01:31:22:375
  END: 01:31:22:390
ARRAYLIST SEARCH
START: 01:31:22:390
  END: 01:31:22:437

同様にCollectionの処理も作って試してみた結果が上記。ArrayListだと、For Eachの検索で、1〜10000の数値から8000を探すのに約15ミリ秒。遅いケースでも30ミリ秒。ところが、Collectionだと、上記の例で860ミリ秒。遅い場合だと、2秒近くかかっている場合もあった。
というわけで、キー検索を用いない単純突っ込み&保持であれば、ArrayListが速い。