ベンチマーク(2)


Excel 2003とExcel 2007で、並べ替えの速度を比較してみました。

セル範囲A1:A60000にランダムな数値を入力し、この範囲を並べ替えます。

並べ替えのコードは、マクロ記録で生成されたコードを使いました。

まず、Excel 2003の結果からご覧ください。

Sub Macro1()    ''マクロ記録で生成されたままのコード
    Dim i As Long, j As Long
    Dim Start As Long, Finish As Long
    Application.ScreenUpdating = False
    ''60000個の乱数を入力
    For i = 1 To 10
        For j = 1 To 60000
            Randomize
            Cells(j, 1) = Int(Rnd() * 1000000)
        Next j
        Start = GetTickCount()
        ''マクロ記録で生成されたコード(ここから)
        Range("A1:A60000").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:= _
            xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
            SortMethod:=xlPinYin, DataOption1:=xlSortNormal
        ''マクロ記録で生成されたコード(ここまで)
        Finish = GetTickCount()
        Debug.Print (Finish - Start) / 1000 & "秒"
    Next i
    Application.ScreenUpdating = True
End Sub
1回目 0.250秒
2回目 0.250秒
3回目 0.234秒
4回目 0.250秒
5回目 0.281秒
6回目 0.250秒
7回目 0.250秒
8回目 0.250秒
9回目 0.250秒
10回目 0.234秒
平均 0.250秒

マクロ記録で生成されるコードは、決して最適化されていません。指定しなくてもいいプロパティなども律儀に規定値を指定したりしますので、不要な部分を削ったコードでもう一度やってみました。

Sub Macro2()    ''シンプルにしたコード
    Dim i As Long, j As Long
    Dim Start As Long, Finish As Long
    Application.ScreenUpdating = False
    ''60000個の乱数を入力
    For i = 1 To 10
        For j = 1 To 60000
            Randomize
            Cells(j, 1) = Int(Rnd() * 1000000)
        Next j
        Start = GetTickCount()
        Range("A1:A60000").Sort Key1:=Range("A1")
        Finish = GetTickCount()
        Debug.Print (Finish - Start) / 1000 & "秒"
    Next i
    Application.ScreenUpdating = True
End Sub
1回目 0.266秒
2回目 0.235秒
3回目 0.234秒
4回目 0.250秒
5回目 0.234秒
6回目 0.250秒
7回目 0.265秒
8回目 0.250秒
9回目 0.250秒
10回目 0.234秒
平均 0.247秒

あまり変わりませんね。差は誤差の範囲でしょう。

さて、同じように60000個の数値をExcel 2007で並べ替えてみます。こちらも最初は、マクロ記録で生成されたコードを使います。

なお、見ていただくとわかりますが、並べ替えに関するオブジェクトはExcel 2007で新しくなっています

Sub Macro3()    ''マクロ記録されたままのコード
    Dim i As Long, j As Long
    Dim Start As Long, Finish As Long
    Application.ScreenUpdating = False
    ''60000個の乱数を入力
    For i = 1 To 10
        For j = 1 To 60000
            Randomize
            Cells(j, 1) = Int(Rnd() * 1000000)
        Next j
        Start = GetTickCount()
        ''マクロ記録で生成されたコード(ここから)
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A1"), _
            SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        With ActiveWorkbook.Worksheets("Sheet1").Sort
            .SetRange Range("A1:A60000")
            .Header = xlNo
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
        ''マクロ記録で生成されたコード(ここまで)
        Finish = GetTickCount()
        Debug.Print (Finish - Start) / 1000 & "秒"
    Next i
    Application.ScreenUpdating = True
End Sub
1回目 0.375秒
2回目 0.375秒
3回目 0.391秒
4回目 0.391秒
5回目 0.375秒
6回目 0.469秒
7回目 0.375秒
8回目 0.390秒
9回目 0.375秒
10回目 0.391秒
平均 0.391秒

Excel 2003に比べて6割ほど遅くなったでしょうか。

こちらも、マクロ記録で生成されたコードから不要部分をカットしてみましょう。

Sub Macro2()    ''シンプルにしたコード
    Dim i As Long, j As Long
    Dim Start As Long, Finish As Long
    Application.ScreenUpdating = False
    ''60000個の乱数を入力
    For i = 1 To 10
        For j = 1 To 60000
            Randomize
            Cells(j, 1) = Int(Rnd() * 1000000)
        Next j
        Start = GetTickCount()
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A1")
        With ActiveWorkbook.Worksheets("Sheet1").Sort
            .SetRange Range("A1:A60000")
            .Apply
        End With
        Finish = GetTickCount()
        Debug.Print (Finish - Start) / 1000 & "秒"
    Next i
    Application.ScreenUpdating = True
End Sub
1回目 0.359秒
2回目 0.391秒
3回目 0.391秒
4回目 0.391秒
5回目 0.375秒
6回目 0.391秒
7回目 0.375秒
8回目 0.390秒
9回目 0.375秒
10回目 0.375秒
平均 0.381秒

気落ち速くなりましたかね。まぁ、ほとんど差はないと見ていいでしょう。

続いてもう一つ確認です。

Excel 2007では、このように新しいオブジェクトなどが新設されていますが、Excel 2003までの古いオブジェクトもそのまま使えるようになっています。つまり、Excel 2003で実行したコードは、Excel 2007でも同じように動作するはずなんです。上記のうち、Excel 2003で検証したコード「Sub Macro2 (シンプルにしたコード)」を、そのままExcel 2007で実行してみましょう。こちらは、結果だけお見せします。

1回目 0.406秒
2回目 0.391秒
3回目 0.391秒
4回目 0.406秒
5回目 0.406秒
6回目 0.406秒
7回目 0.406秒
8回目 0.421秒
9回目 0.421秒
10回目 0.406秒
平均 0.406秒

一番遅い結果となりましたね。

以上の検証から次のことがわかりました。

  1. Excel 2007では"並べ替え"のオブジェクトが新しくなった
  2. "並べ替え"の動作は、Excel 2003より遅くなった
  3. 古いオブジェクトをExcel 2007で使うと遅くなった

並べ替えの動作検証だけでは何とも言えませんが、Excel 2007のマクロで速度を気にするなら、Excel 2007用の新しいオブジェクトを使えってことでしょうか。引き続き、いろんな動作で速度を検証してみようと思います。