前一段时间,我要求提供一个快速链接列表,建议是使用类。 (How to construct a Minimal Excel-VBA Linked List without using custom Classes in VBA)。我以为我可以解决这个问题,在我开始增加清单的长度之前,它工作得很好。程序完成后,Excel变得无响应。
我将此追溯到对象的破坏。下面的代码测量“ dumclass”对象(完全空的类,根本没有方法或属性)的生成和销毁的运行时间。
基本上,时钟开始滴答(tic),我在数组和集合中填充了dumclasses,为了进行比较,在数组中添加了collection。我检查时间(toc),然后测量擦除阵列和集合的时间。
看来,删除数组/集合后,“垃圾收集” dumclasss对象所花费的时间随着集合中dumbclass对象的数量“呈指数增长”。存储在集合中的dumclass的垃圾集合所花费的时间是存储在数组中的dumclass的两倍。
但是,将此与收集数组进行比较,在该数组中,垃圾收集的时间实际上为零。
我进行了一些阅读,发现这个(https://stackoverflow.com/a/777331/10312272)链接到.Net中的垃圾收集。可能是Excel使用带有大小对象的类似系统吗? (发问后的帖子:我试图将数组分成几块;这对总处理时间没有影响)
我想知道其他人是否遇到过这种情况,以及在使用大量对象时是否有办法避免较长的垃圾收集时间?
非常感谢
Option Explicit
Declare Function GetTickCount Lib "kernel32" () As Long
Sub odd()
Dim Lengths
Lengths = Array(10, 100, 1000, 3000, 10000, 63000, 100000, 300000)
Dim Length, k, dt1, dt2, dt3, dt4, coll As Collection
dp "length", "t.setup", "t.del coll", "t.del/cls", "t.del arr", "t.del/cls", "t.del arr", "t.del/collection"
Dim a(), c()
For Each Length In Lengths
ReDim a(1 To Length)
ReDim c(1 To Length)
Set coll = New Collection
tic
For k = 1 To Length
'create a collection of dum(my)classes
coll.Add New dumclass
'create an array of dum classes
Set a(k) = New dumclass
'create an array of colections
Set c(k) = New Collection
c(k).Add 3
c(k).Add 3
c(k).Add 3
Next
dt1 = toc
'delete the collection of dumbclasses
tic
Set coll = New Collection
dt2 = toc
'delete the array of dumclasses
tic
Erase a
dt3 = toc
'delete the array of collections
tic
Erase c
dt4 = toc
dp Length, dt1, dt2, Int(dt2 * 1000 / Length) / 1000, dt3, Int(dt3 * 1000 / Length) / 1000, dt4, Int(dt4 * 1000 / Length) / 1000, "ms"
Next
dp "done"
End Sub
Private Sub dp(Optional a1 = "", Optional a2 = "", Optional a3 = "", Optional a4 = "", Optional a5 = "", Optional a6 = "", Optional a7 = "", Optional a8 = "", Optional a9 = "", Optional a10 = "", Optional a11 = "", Optional a12 = "")
Debug.Print a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12
End Sub
Private Function tic(Optional passedSinceLastcall As Boolean = False)
Static LastTime As Long, nU As Long
nU = GetTickCount
If passedSinceLastcall Then
If LastTime = 0 Then
tic = 0
Else
tic = nU - LastTime
End If
Else
tic = nU
End If
LastTime = nU
End Function
Private Function toc()
toc = tic(True)
End Function