在过去的几年里,我有一个项目进行了点点滴滴的更改和修改,并且从一个代码模块到下一个代码模块的大部分内容都是非标准化的。在某些情况下,我使用了一个Scripting.Dictionary
对象,而在其他情况下,我有一个Collection
对象。对于其中的每一个,有时会按 count (即For i = 1 to Obj.Count
)进行迭代,有时会按For...Each
.
我想尽可能多地对这些案例应用相同的逻辑,以使未来的变化希望更加无缝,但我不确定哪种方法最好。(我相信为一种或另一种方法制作了一些特定的案例,但我也很确定某些代码可以使用任何可用的方法。)
我尝试创建一个测试子来帮助我确定哪种方法效果最好,但结果有些不一致。Item
总体而言,循环通过a中的每个似乎Dictionary
更快,但在某些情况下,我的测试结果显示通过Item
a 中的每个循环Collection
更快。差异可能取决于任何给定时间系统中发生的所有其他事情。
我想知道是否有人对哪种方法始终最快有明确的答案,假设循环中的所有其他方法都是相同的。或者,有什么方法可以改进我的测试子,使其在返回结果时更加一致,以便我自己回答这个问题?
我想出的测试代码:
Option Explicit
Sub Test_Dictionary_Iteration_Speed()
Dim Coll1 As New Collection, Coll2 As New Collection
Dim Dict1 As New Scripting.Dictionary, Dict2 As New Scripting.Dictionary, Dict3 As New Scripting.Dictionary
Dim i As Integer, j As Integer, l As Integer
Dim StartTime As Single, StopTime As Single
Dim v As Variant
Dim Obj As TestObject 'A custom Class that has only one member variable, MainVal, and no functions/subs
For i = 0 To 32766
Set Obj = New TestObject
Obj.MainVal = i
Dict1.Add CStr(i), Obj
Dict2.Add CStr(i), Obj
Dict3.Add CStr(i), Obj
Coll1.Add Obj, CStr(i)
Coll2.Add Obj, CStr(i)
Next i
StartTime = Timer()
For j = 0 To Dict1.Count - 1
l = CInt(Dict1(CStr(j)).MainVal)
Set Obj = Dict1(CStr(l)) 'Do something useful within the loop
Set Obj = Nothing
Dict1.Remove CStr(l)
Next j
StopTime = Timer()
Debug.Print "Dict1 for x to y: " & StopTime - StartTime
StartTime = Timer()
For Each v In Dict2.Items
l = CInt(v.MainVal)
Set Obj = Dict2(CStr(l))
Set Obj = Nothing
Dict2.Remove CStr(l)
Next v
StopTime = Timer()
Debug.Print "Dict2 for each item: " & StopTime - StartTime
StartTime = Timer()
For Each v In Dict3.Keys
l = CInt(Dict3(v).MainVal)
Set Obj = Dict3(CStr(l))
Set Obj = Nothing
Dict3.Remove CStr(l)
Next v
StopTime = Timer()
Debug.Print "Dict3 for each key: " & StopTime - StartTime
'---------- Division between Dictionary and Collection
StartTime = Timer()
For j = 0 To Coll1.Count - 1
l = CInt(Coll1(CStr(j)).MainVal)
Set Obj = Coll1(CStr(l))
Set Obj = Nothing
Coll1.Remove CStr(l)
Next j
StopTime = Timer()
Debug.Print "Coll1 for x to y: " & StopTime - StartTime
StartTime = Timer()
For Each v In Coll2
l = CInt(v.MainVal)
Set Obj = Coll2(CStr(l))
Set Obj = Nothing
Coll2.Remove CStr(l)
Next v
StopTime = Timer()
Debug.Print "Coll2 for each item: " & StopTime - StartTime
Debug.Print vbNewLine & "-----" & vbNewLine
End Sub
输出的真实示例,表明“最佳”选项并不总是相同:
x 到 y 的 Dict1:0.2011719
每个项目的 Dict2:0.1738281
每个键的 Dict3:0.2167969
x 到 y 的 Coll1:0.2050781
每个项目的 Coll2:0.1386719
Dict1 for x to y: 0.1875
Dict2 for each item: 0.171875
Dict3 for each key: 0.234375
Coll1 for x to y: 0.2050781
Coll2 for each item: 0.1542969
Dict1 for x to y: 0.25
Dict2 for each item: 0.21875
Dict3 for each key: 0.265625
Coll1 for x to y: 0.234375
Coll2 for each item: 0.171875
x 到 y 的 Dict1:0.265625
每个项目的 Dict2:0.203125
每个键的 Dict3:0.296875
x 到 y 的 Coll1:0.234375
每个项目的 Coll2:0.21875
Dict1 for x to y: 0.265625
Dict2 for each item: 0.1875
Dict3 for each key: 0.234375
Coll1 for x to y: 0.203125
Coll2 for each item: 0.15625
Dict1 for x to y: 0.28125
Dict2 for each item: 0.1875
Dict3 for each key: 0.25
Coll1 for x to y: 0.234375
Coll2 for each item: 0.1875
x 到 y 的 Dict1 :0.28125
每个项目的 Dict2:0.21875
每个键的 Dict3:0.328125
x 到 y 的 Coll1:0.234375
每个项目的 Coll2:0.234375