後ろから読む派

Scripting.Dictionary の性能を測ってみた。

  • 追加: Add メソッドでデータ追加。
  • 取得: Item メソッドでデータ取得。

の 2 パターンを、件数多くして計ってみた。

           件数  100000  200000 300000 400000
  追加              2~3    9~10     21  37~38
  全件取得          2~3    9~10  21~22     39

  -- 以下は同一キーで 300000 回繰返し --
  取得(#1)            4       9     13     17
  取得(#100000)       1       4    8~9     13
  取得(#200000)       -       1      5      8
  取得(#300000)       -       -      1      4

「追加」と「取得」でコードが若干違うので両者の比較はできない。上表の単位は「秒」だけど、これをもって「Add と Item が等速だ」とはいえないので注意。精度も低いし。
で、「追加」「全件取得」ははっきりわかんないので後回し。
下 4 つの「取得」なんだけど、これでわかるのは、Scripting.Dictionary#Item は、どうやら、最後に追加した要素から最初に追加した要素へとシーケンシャルな検索をやっているらしい、ということ。
以下は、テストに使ったコード。

Public Sub CheckDictionaryPerformance()
    Dim d1  As New Scripting.Dictionary
    Dim d2  As New Scripting.Dictionary
    Dim d3  As New Scripting.Dictionary
    Dim d4  As New Scripting.Dictionary
    
    Debug.Print LapDictionaryAddPerformance(d1, 100000)
    Debug.Print LapDictionaryAddPerformance(d2, 200000)
    Debug.Print LapDictionaryAddPerformance(d3, 300000)
    Debug.Print LapDictionaryAddPerformance(d4, 400000)
        
    Debug.Print LapDictionaryGetPerformance(d1, 100000)
    Debug.Print LapDictionaryGetPerformance(d2, 200000)
    Debug.Print LapDictionaryGetPerformance(d3, 300000)
    Debug.Print LapDictionaryGetPerformance(d4, 400000)
        
    Debug.Print LapDictionaryGetPerformance2(d1, 300000, 1)
    Debug.Print LapDictionaryGetPerformance2(d2, 300000, 1)
    Debug.Print LapDictionaryGetPerformance2(d3, 300000, 1)
    Debug.Print LapDictionaryGetPerformance2(d4, 300000, 1)
        
    Debug.Print LapDictionaryGetPerformance2(d1, 300000, 100000)
    Debug.Print LapDictionaryGetPerformance2(d2, 300000, 100000)
    Debug.Print LapDictionaryGetPerformance2(d3, 300000, 100000)
    Debug.Print LapDictionaryGetPerformance2(d4, 300000, 100000)
        
    Debug.Print LapDictionaryGetPerformance2(d2, 300000, 200000)
    Debug.Print LapDictionaryGetPerformance2(d3, 300000, 200000)
    Debug.Print LapDictionaryGetPerformance2(d4, 300000, 200000)
        
    Debug.Print LapDictionaryGetPerformance2(d3, 300000, 300000)
    Debug.Print LapDictionaryGetPerformance2(d4, 300000, 300000)
        
End Sub

' Dictionary に nSize 個の要素追加を行い、かかった秒数を返す
Private Function LapDictionaryAddPerformance(ByVal oDic As Scripting.Dictionary, ByVal nSize As Long) As Long
    Dim I               As Long
    Dim dtStartTime     As Date
    Dim dtEndTime       As Date
    
    dtStartTime = Now
    
    For I = 1 To nSize
        oDic.Add I, I + 1
    Next
    
    dtEndTime = Now
    
    LapDictionaryAddPerformance = DateDiff("s", dtStartTime, dtEndTime)
End Function

' Dictionary に nSize 個の要素取得を行い、かかった秒数を返す
Private Function LapDictionaryGetPerformance(ByVal oDic As Scripting.Dictionary, ByVal nCount As Long) As Long
    Dim I               As Long
    Dim dtStartTime     As Date
    Dim dtEndTime       As Date
    
    dtStartTime = Now
    
    For I = 1 To nCount
        Debug.Assert oDic.Item(I) = I + 1
    Next
    
    dtEndTime = Now
    
    LapDictionaryGetPerformance = DateDiff("s", dtStartTime, dtEndTime)
End Function

' Dictionary から nCount 回の要素取得を行い、かかった秒数を返す
Private Function LapDictionaryGetPerformance2(ByVal oDic As Scripting.Dictionary, ByVal nCount As Long, ByVal nKey As Long) As Long
    Dim I               As Long
    Dim dtStartTime     As Date
    Dim dtEndTime       As Date
    
    dtStartTime = Now
    
    For I = 1 To nCount
        Debug.Assert oDic.Item(nKey) = nKey + 1
    Next
    
    dtEndTime = Now
    
    LapDictionaryGetPerformance2 = DateDiff("s", dtStartTime, dtEndTime)
End Function