vba - 解决对象类型评估的性能问题 (Scripting.Dictionary)
问题描述
当我尝试优化我的代码时,我偶然发现了一个重大的性能问题。我发现 TypeName(object) 对于某些类型的对象来说非常慢。例如,运行具有以下类型的变体的 TypeName 需要以下时间,这是由该基准测试模块测量的。
- 双倍为 0.3 µs
- Scripting.Dictionary 为 402 µs
- Scripting.FilesystemObject 为 1.3 µs
- 收集时间为 1.0 µs
因此,为 Scripting.Dictionary 对象运行 TypeName 需要很长时间。在一个循环中,使用这 2000 次将需要将近 1 秒!
解决方案
解决方案是使用 VBA 中内置的 TypeOf 构造。以下代码进行了基准测试:
Option Explicit
Sub TestTypeName()
Dim Var1 As Variant
Dim Var2 As Variant
Dim Var3 As Variant
Dim Var4 As Variant
Dim i As Long
Var1 = 12#
Set Var2 = New Scripting.Dictionary
Set Var3 = New Scripting.FileSystemObject
Set Var4 = New Collection
For i = 1 To 10000
If VarIsOfTypeCollection_TN1(Var1) Then 'do stuff
End If
If VarIsOfTypeCollection_TN2(Var2) Then 'do stuff
End If
If VarIsOfTypeCollection_TN3(Var3) Then 'do stuff
End If
If VarIsOfTypeCollection_TN4(Var4) Then 'do stuff
End If
If VarIsOfTypeCollection_TO1(Var1) Then 'do stuff
End If
If VarIsOfTypeCollection_TO2(Var2) Then 'do stuff
End If
If VarIsOfTypeCollection_TO3(Var3) Then 'do stuff
End If
If VarIsOfTypeCollection_TO4(Var4) Then 'do stuff
End If
Next
End Sub
'Four identical functions checking if argument is collection using TypeaName.
'I have four separate functions to be able to benchmark them separately
Function VarIsOfTypeCollection_TN1(Vin As Variant) As Boolean
VarIsOfTypeCollection_TN1 = TypeName(Vin) = "Collection"
End Function
Function VarIsOfTypeCollection_TN2(Vin As Variant) As Boolean
VarIsOfTypeCollection_TN2 = TypeName(Vin) = "Collection"
End Function
Function VarIsOfTypeCollection_TN3(Vin As Variant) As Boolean
VarIsOfTypeCollection_TN3 = TypeName(Vin) = "Collection"
End Function
Function VarIsOfTypeCollection_TN4(Vin As Variant) As Boolean
VarIsOfTypeCollection_TN4 = TypeName(Vin) = "Collection"
End Function
'Four identical functions checking if argument is collection using TypeOf.
'I have four separate functions to be able to benchmark them separately
Function VarIsOfTypeCollection_TO1(Vin As Variant) As Boolean
VarIsOfTypeCollection_TO1 = TypeOf Vin Is Collection
End Function
Function VarIsOfTypeCollection_TO2(Vin As Variant) As Boolean
VarIsOfTypeCollection_TO2 = TypeOf Vin Is Collection
End Function
Function VarIsOfTypeCollection_TO3(Vin As Variant) As Boolean
VarIsOfTypeCollection_TO3 = TypeOf Vin Is Collection
End Function
Function VarIsOfTypeCollection_TO4(Vin As Variant) As Boolean
VarIsOfTypeCollection_TO4 = TypeOf Vin Is Collection
End Function
因此,当应用于 Scripting.Dictionary 对象时,使用 TypeOf 的构造总是非常快 (<<1µs),并且比使用 TypeName 的构造快近 2000 倍。
推荐阅读
- csv - 改组分隔的 csv 文件中的列
- javascript - 如何为导出的 javascript 对象编写类型文件
- html - div元素问题
- macos - 在clang和gcc之间选择g++的编译器
- tensorflow - Google Colab Tensorflow 模型未使用 epoch 中的所有样本
- kotlin - Kotlin 静态初始化中的 ExceptionInInitializerError
- python - Python split() 复制
- c# - 实例化数组中的特定对象时如何触发事件?
- python - 在python中附加文本文件
- java - 如何使用 jdbc 从表行中获取数据?