Here are results of some tests intended to compare the relative speed of storing and reading a large group of items in Collections vs Arrays using the methods previously discussed. Further below I've posted the code used so others can repeat or build upon it.
The first test was to Store 12,345,678 items that were the result of a simple multiplication.
On a realative basis, storing items in an array when one knows the number of items is the fastest.
To shg's point, all methods were nominally very fast- this shouldn't be a factor in deciding which handling method.
The test's supported that the method of Redimming in Chunks that Rick suggested is more efficient than Redimming as each item is added.
Comparative Results of Store-Only with 1,234,567 items:
Collection: 0.19 seconds
Array_Known_Size: 0.02 seconds
Array_Unknown_Size_Redim_Each : 1.25 seconds
Array_Unknown_Size_Redim_Chunks : 0.16 seconds
The second test was to Store the items and then Read each one to a variable.
The results of this were surprising. The Collection did very poorly. It locked up my computer and I had to run a follow up test with a scaled down the number of items to test the relative speed.
Comparative Results of Store_then_Read with 1,234,567 items:
Collection: N/A Locked up computer.
Array_Known_Size: 0.08 seconds
Array_Unknown_Size_Redim_Each : 1.25 seconds
Array_Unknown_Size_Redim_Chunks : 0.15 seconds
Results of a testing with a smaller sample size.
Comparative Results of Store_then_Read with 123,456 items:
Collection: 31.03 seconds
Array_Known_Size: 0 seconds
Array_Unknown_Size_Redim_Each : 0.03 seconds
Array_Unknown_Size_Redim_Chunks : 0 seconds
So it would appear a Collection is significantly less efficient than an Array at doing a large number of Reads from a large group of stored items.
Code:
Sub Compare_Times_Store_Only()
Const lNumberOfItems As Long = 1234567
Debug.Print vbCr & "Comparative Results of Store-Only with " _
& Format(lNumberOfItems, "#,###") & " items:"
Call Test_Collection(lNumberOfItems, False)
Call Test_Array_Known_Size(lNumberOfItems, False)
Call Test_Array_Unknown_Size_Redim_Each(lNumberOfItems, False)
Call Test_Array_Unknown_Size_Redim_Chunks(lNumberOfItems, False)
End Sub
Sub Compare_Times_Store_then_Read()
Const lNumberOfItems As Long = 1234567
Debug.Print vbCr & "Comparative Results of Store_then_Read with " _
& Format(lNumberOfItems, "#,###") & " items:"
'Call Test_Collection(lNumberOfItems, True) 'locks up if over ~200K items
Call Test_Array_Known_Size(lNumberOfItems, True)
Call Test_Array_Unknown_Size_Redim_Each(lNumberOfItems, True)
Call Test_Array_Unknown_Size_Redim_Chunks(lNumberOfItems, True)
End Sub
Sub Test_Collection(lNumberOfItems As Long, bRead As Boolean)
Dim dblStart As Double: dblStart = Timer
Dim colVals As New Collection
Dim i As Long, lReadMe As Long
On Error Resume Next
For i = 1 To lNumberOfItems
colVals.Add i * 2
Next i
If bRead Then
For i = 1 To colVals.Count
lReadMe = colVals(i)
Next i
End If
Debug.Print "Collection: " _
& Round((Timer - dblStart), 2) & " seconds"
End Sub
Sub Test_Array_Known_Size(lNumberOfItems As Long, bRead As Boolean)
Dim dblStart As Double: dblStart = Timer
Dim lArray() As Long, lReadMe As Long, i As Long
ReDim lArray(1 To lNumberOfItems)
For i = 1 To lNumberOfItems
lArray(i) = i * 2
Next i
If bRead Then
For i = 1 To UBound(lArray)
lReadMe = lArray(i)
Next i
End If
Debug.Print "Array_Known_Size: " _
& Round((Timer - dblStart), 2) & " seconds"
End Sub
Sub Test_Array_Unknown_Size_Redim_Each(lNumberOfItems As Long, bRead As Boolean)
Dim dblStart As Double: dblStart = Timer
Dim i As Long, lReadMe As Long
Dim lArray() As Long
For i = 1 To lNumberOfItems
ReDim Preserve lArray(1 To i)
lArray(i) = i * 2
Next i
If bRead Then
For i = 1 To UBound(lArray)
lReadMe = lArray(i)
Next i
End If
Debug.Print "Array_Unknown_Size_Redim_Each : " _
& Round((Timer - dblStart), 2) & " seconds"
End Sub
Sub Test_Array_Unknown_Size_Redim_Chunks(lNumberOfItems As Long, bRead As Boolean)
Dim dblStart As Double: dblStart = Timer
Dim lCounter As Long, i As Long, lReadMe As Long
Dim lArray() As Long
Const lChunkSize As Long = 10000
ReDim lArray(1 To lChunkSize)
Do While lCounter <> lNumberOfItems
lCounter = lCounter + 1
If lCounter > UBound(lArray) Then
ReDim Preserve lArray(1 To UBound(lArray) + lChunkSize)
End If
lArray(lCounter) = lCounter * 2
Loop
ReDim Preserve lArray(1 To lCounter)
If bRead Then
For i = 1 To UBound(lArray)
lReadMe = lArray(i)
Next i
End If
Debug.Print "Array_Unknown_Size_Redim_Chunks : " _
& Round((Timer - dblStart), 2) & " seconds"
End Sub