rpe*_*z86 5 excel vba excel-vba
我一直在尝试使用类模块开发一个宏,但是与UDT相比,get/let似乎需要很长时间.我真的很感兴趣为什么会这样,有人可以解释一下吗?我只发现了讨论功能/子执行的讨论,这似乎同样快.
目前的问题是设置一个属性,该类需要大约3000毫秒(200万次)和120毫秒使用UDT进行相同操作.
我正在尝试决定是否应该建议宏开发人员在需要获取或设置大量属性时避免使用类模块.只使用这个作为我应该的数据,但也许你有不同的见解.
我想明白为什么这么慢.也许我只是做错了什么.
示例代码:
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
Run Code Online (Sandbox Code Playgroud)
和类模块(名为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
Run Code Online (Sandbox Code Playgroud)
A. *_*ebb 10
首先,我强烈建议使用高分辨率计时器,这样您就不必测试尽可能多的迭代次数.请参阅CTimer使用QueryPerformanceCounter.
这是我的机器上的基线,10K迭代,高精度计时器
Sub TimeUDT()
Dim i As Long
Dim timer As New CTimer
timer.StartCounter
Dim participants(1 To 10000) As Participant
For i = 1 To 10000
participants(i).Name = "TestName"
participants(i).Gender = 1
Next
Debug.Print "Elapsed time: " & timer.TimeElapsed & " ms"
End Sub
Elapsed time: 1.14359022404999 ms
Run Code Online (Sandbox Code Playgroud)
不管你信不信,你实际上是在你的循环中获得对象创建的命中.在启动计时器之前,在循环中显式创建它们并查看差异:
之前
Sub TimeCls()
Dim i As Long
Dim timer As New CTimer
Dim participants(1 To 10000) As New clsParticipant
timer.StartCounter
For i = 1 To 10000
participants(i).Name = "TestName"
participants(i).Gender = 1
Next
Debug.Print "Elapsed time: " & timer.TimeElapsed & " ms"
End Sub
Elapsed time: 24.9600996727434 ms
Run Code Online (Sandbox Code Playgroud)
后
Sub TimeCls()
Dim i As Long
Dim timer As New CTimer
'Dim participants(1 To 10000) As New clsParticipant
Dim participants(1 To 10000) As clsParticipant
For i = 1 To 10000
Set participants(i) = New clsParticipant
Next i
timer.StartCounter
For i = 1 To 10000
participants(i).Name = "TestName"
participants(i).Gender = 1
Next
Debug.Print "Elapsed time: " & timer.TimeElapsed & " ms"
End Sub
Elapsed time: 4.66722880515984 ms
Run Code Online (Sandbox Code Playgroud)
这仅比基线慢4倍(在现在从测量中排除对象创建命中之后).如果进一步的声明iGender和sName公开和直接变异它们,那么性能更接近底线,所以大部分的性能命中的其余部分是从Let间接.
Sub TimeCls()
Dim i As Long
Dim timer As New CTimer
Dim participants(1 To 10000) As clsParticipant
For i = 1 To 10000
Set participants(i) = New clsParticipant
Next i
timer.StartCounter
For i = 1 To 10000
'participants(i).Name = "TestName"
'participants(i).Gender = 1
participants(i).sName = "TestName"
participants(i).iGender = 1
Next
Debug.Print "Elapsed time: " & timer.TimeElapsed & " ms"
End Sub
Elapsed time: 1.71887815565976 ms
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1730 次 |
| 最近记录: |