【发布时间】:2014-05-30 00:25:26
【问题描述】:
我一直在尝试使用类模块开发宏,但与 UDT 相比,get/let 似乎需要很长时间。我真的很感兴趣这是为什么,有人可以解释一下吗?我只发现讨论函数/子执行的讨论,这似乎同样快。
当前的问题是设置一个属性,该类大约需要 3000 毫秒(对于 200 万个 let),而使用 UDT 执行相同操作需要 120 毫秒。
我正在尝试决定是否应该建议宏开发人员在需要获取或设置大量属性时避免使用类模块。我应该只使用这个作为数据,但也许你有不同的见解。
我想了解为什么速度这么慢。也许我只是做错了什么。
示例代码:
Public Type Participant
Name As String
Gender As Integer
End Type
Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub TimeUDT()
Dim i As Long
Dim startMs As Long
startMs = GetTickCount
Dim participants(1 To 1000000) As Participant
For i = 1 To 1000000
participants(i).Name = "TestName"
participants(i).Gender = 1
Next
Debug.Print GetTickCount - startMs
End Sub
Sub TimeCls()
Dim i As Long
Dim startMs As Long
Dim participants(1 To 1000000) As New clsParticipant
startMs = GetTickCount
For i = 1 To 1000000
participants(i).Name = "TestName"
participants(i).Gender = 1
Next
Debug.Print GetTickCount - startMs
End Sub
以及类模块(名为 clsParticipant):
Private iGender As Integer
Private sName As String
Public Property Let Gender(value As Integer)
iGender = value
End Property
Public Property Get Gender() As Integer
Gender = iGender
End Property
Public Property Get Name() As String
Name = sName
End Property
Public Property Let Name(value As String)
sName = value
End Property
【问题讨论】:
-
我的猜测是你正在寻找一个可扩展性问题并且不一定执行缓慢。如果您对少量迭代进行测试,我猜它们每次执行的时间仅为 300 毫秒的一小部分。如果您的设计确实需要 RAM 中的类的 200 万个实例,我认为您最好看看不同的设计。
-
是的,您遇到了与几年前我必须处理的类对象相同的问题。我被“起草”来分析一个已在全球范围内投入生产的大型访问数据库,它像狗一样运行。我在每个函数和子例程中都放置了计时器,发现对类的引用很疯狂。我切换到一些全局变量和宾果游戏!我从不费心去理解为什么那些特定的慢,但它与初始化有关(不,它们是非常简单的类)。
-
@rheitzman : 不幸的是,由于这是一个正在改造的大型项目,目前无法更改设计。确实,例如为 10.000 个对象运行它需要 0 毫秒,但真正的问题是需要设置很多属性和少量(打开的工作簿的数量)实例。它用于保存在计算每个打开的工作簿时使用的数据。因此,由于数据集太大且类模块太慢,UDT 不是一个选项。
-
@WayneG.Dunn :如果我理解正确,您是在类模块之外使用全局变量吗?我们需要将这些作为实例,否则我们必须在另一个模块中保留一个单独的设置数组。就初始化而言:我在初始化类实例数组后启动计时器,所以我想在这种情况下这不会是问题。
-
我真的不理解关于这个问题的 3 个“缺乏足够信息”的近距离投票。它写得很清楚,并包含一个 SSCCE 来证明问题。它的质量比 excel、vba 标签的标准票价高得多。