結論:コレクションオブジェクトからループで値を取り出す際にFor文を使ってはいけない。
コレクションオブジェクトに値を代入し終える
時間と取り出す際の時間を計測してみた。
比較用に配列でも同じ事をしてみた。
サンプルコード
1000~5万データで各データ10回テストした平均の時間を記載してあります。
単位は[ms]です。
たった1回でもコレクションオブジェクトに対しインデックスを
使って値を取り出しただけでこれほどの時間がかかるわけです。
例えば、1つのループ内で3回、インデックス経由で呼出を行うと
3倍時間がかかるわけです。
ただし、問題はコレクションオブジェクトに対し、インデックスを利用して
値を取り出すことにあって、キー経由で取り出す分には影響がないということです。
上記コードで、コレクションオブジェクトの値を取り出す部分を
For文からFor Each文に切り替えると以下の通りになります。
単位は[ms]です。
サンプルコード
出したほうがパフォーマンスがよいってことですね。
コレクションオブジェクトに値を代入し終える
時間と取り出す際の時間を計測してみた。
比較用に配列でも同じ事をしてみた。
サンプルコード
Option Explicit Declare Function GetTickCount Lib "kernel32" () As Long Sub SampleCode() Dim Temp As Long Dim BaseTime As Double, i As Long Dim MaxNumber As Long: MaxNumber = 1000 Dim VarCollection As New Collection Dim VarArray() As Long '■コレクションオブジェクトに値を格納する BaseTime = GetTickCount For i = 0 To MaxNumber VarCollection.Add i Next Debug.Print "Collection[In] :" & GetTickCount - BaseTime BaseTime = GetTickCount For i = 1 To MaxNumber + 1 Temp = VarCollection.Item(i) Next Debug.Print "Collection[In] :" & GetTickCount - BaseTime '■配列に値を格納する BaseTime = GetTickCount For i = 0 To MaxNumber ReDim Preserve VarArray(i) VarArray(i) = i Next Debug.Print "Collection[In] :" & GetTickCount - BaseTime BaseTime = GetTickCount For i = 0 To MaxNumber Temp = VarArray(i) Temp = VarArray(i) Next Debug.Print "Collection[In] :" & GetTickCount - BaseTime End Sub
1000~5万データで各データ10回テストした平均の時間を記載してあります。
単位は[ms]です。
たった1回でもコレクションオブジェクトに対しインデックスを
使って値を取り出しただけでこれほどの時間がかかるわけです。
例えば、1つのループ内で3回、インデックス経由で呼出を行うと
3倍時間がかかるわけです。
ただし、問題はコレクションオブジェクトに対し、インデックスを利用して
値を取り出すことにあって、キー経由で取り出す分には影響がないということです。
上記コードで、コレクションオブジェクトの値を取り出す部分を
For文からFor Each文に切り替えると以下の通りになります。
単位は[ms]です。
サンプルコード
Option Explicit Declare Function GetTickCount Lib "kernel32" () As Long Sub SampleCode2() Dim Temp As Long Dim BaseTime As Double, i As Long, v As Variant Dim MaxNumber As Long: MaxNumber = 50000 Dim VarCollection As New Collection '■コレクションオブジェクトに値を格納する BaseTime = GetTickCount For i = 0 To MaxNumber VarCollection.Add i Next Debug.Print "Collection[In] :" & GetTickCount - BaseTime BaseTime = GetTickCount For Each v In VarCollection Temp = v Next Debug.Print "Collection[Out]:" & GetTickCount - BaseTime End Subつまり、コレクションオブジェクトはFor Eachで取り
出したほうがパフォーマンスがよいってことですね。
0 件のコメント:
コメントを投稿