背景:我在Excel VBA宏中使用VB.NET COM DLL服务器。 VBA宏只调用DLL中的子例程,传入一个数组。在我的测试中,从VB.NET代码中的数组读取比从VB.NET代码中本地创建的数组中读取要慢得多(10倍),即使它们具有相同的类型。无论VB.NET子例程是否采用数组参数ByRef或ByVal。
,差异仍然存在代码,Excel / VBA方:
Dim x As MyDllTest.MyDllTestClass
Set x = New MyDllTest.MyDllTestClass
Dim arr(10)
Call x.someSub(arr)
VB.NET方面:
Public Class MyDllTestClass
Sub someSub(ByRef arr) ' Changing to ByVal changes nothing
Dim i
For i = 1 To 10000000 ' huge number to show speed difference
Dim x = arr(1 + i Mod 10) ' some useless read
Next i
End Sub
End Class
我已经看到其他问题,人们抱怨VB.NET COM DLL的缓慢,但通常是由于多次调用DLL的互操作开销。在我的情况下,只有一个电话,所以不是这样。
起初我认为这种缓慢可能是由于VBA传递了一些奇怪的数组类型而导致的,这些数组类型不是VB.NET的原生数据,而且对它的操作速度较慢。但MsgBox(TypeName(arr))
表示VB.NET将arr
视为另一个Object()
数组(或Integer()
,Double()
等,具体取决于arr
的方式在VBA代码中初始化)。
然后我想也许ByRef
迫使客户端和服务器之间有一些笨重的互操作,但是在更改为ByVal
之后 - 我认为会复制数组,从而避免任何内存共享问题和使它在功能上等同于本地 - 它仍然一样慢。在VB.NET代码中对本地Object()
数组执行相同的1000万次读取速度要快10倍。咦?
如果有人能帮我理解发生了什么,我真的很感激。对不起,如果我在这里愚蠢(希望它就这么简单);这是我在Windows环境中工作10周后的第一周,我对所有涉及的技术(VBA / VB.NET / DLLs / COM)都很陌生。感谢。