为什么删除阵列所需的时间与阵列中的对象数量不成比例

时间:2019-06-11 14:46:31

标签: arrays excel class garbage-collection

前一段时间,我要求提供一个快速链接列表,建议是使用类。 (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的两倍。

但是,将此与收集数组进行比较,在该数组中,垃圾收集的时间实际上为零。

data table of execution times

我进行了一些阅读,发现这个(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

0 个答案:

没有答案