【发布时间】:2015-01-14 18:23:38
【问题描述】:
我想标题很简单,将变量声明为变体而不是特定的数据类型对 VBA 的性能有什么影响?
也许是因为我没有编程经验,但直觉上它应该会降低性能,因为计算机必须检查分配的数据类型,然后将变量更改为分配的数据类型,而不是立即为其分配值.我还没有找到这方面的一些文献。
【问题讨论】:
我想标题很简单,将变量声明为变体而不是特定的数据类型对 VBA 的性能有什么影响?
也许是因为我没有编程经验,但直觉上它应该会降低性能,因为计算机必须检查分配的数据类型,然后将变量更改为分配的数据类型,而不是立即为其分配值.我还没有找到这方面的一些文献。
【问题讨论】:
这取决于。变体比原生类型慢,但在大多数程序中,这根本不重要。大多数宏都很小,在运行时会被编译,差异可能只有几微秒,你无法察觉。
变体有其优点,我喜欢它们。
所以这取决于你在做什么。如果你的程序在眨眼之间运行,那么避免变体没有任何好处。如果需要时间,请强烈键入您的变量(并正确声明对象 - 见下文)。
如果性能是一个问题,我将在下面提到除此之外的其他问题。
一般问题
设置属性或调用方法时,每个都是CPU中的函数调用。这意味着堆栈设置开销。函数调用比内联代码慢。出于同样的原因,在 VBA 中使用循环而不是函数。
F 或 a start 不要一遍又一遍地指定所有这些属性。除非你改变它们,否则它们不会改变。
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.MatchFuzzy = False
For loop to go through each word pair
.Text = SrcText
.Replacement.Text = DestText
.Find.Execute Replace:=wdReplaceAll
Next
End With
尽量减少点
因此,如果您对性能感兴趣,请尽量减少点(每个点都是一个查找),尤其是在循环中。
有两种方法。一种是如果您要访问不止一次,则将对象设置为最低的对象。
例如(较慢)
set xlapp = CreateObject("Excel.Application")
msgbox xlapp.worksheets(0).name
(更快,因为每次使用对象时都会省略一个点)
set xlapp = CreateObject("Excel.Application")
set wsheet = xlapp.worksheets(0)
msgbox wsheet.name
第二种方式是with。一次只能有一个处于活动状态。
这会跳过 100 次查找。
with wsheet
For x = 1 to 100
msgbox .name
Next
end with
字符串连接
并且不要一次连接一个字符。从 VBScript 程序员那里看到这个。它需要 50,000 字节和多次分配和释放才能生成 100 个字符的字符串。
http://blogs.msdn.com/b/ericlippert/archive/2003/10/20/53248.aspx
读取属性
不要重新读取不会更改的属性,尤其是在进程外或后期绑定时。将它们放入变量中。
对象类型
这里有两个概念 - 进程内或进程外以及早期或晚期绑定。
exefiles 连接到进程外。所有调用都通过 RPC(一种网络协议)进行编组。 Dllfile 正在处理中,函数调用直接通过跳转进行。
早期绑定是set x = objecttype。编写程序时会查找函数。在执行时,程序被硬编码为跳转到存储在该函数的 vtable 中的地址。
延迟绑定设置为x = createobject("objecttype")。每个函数调用都是这样的。 “您好,您有打印命令吗”。 “是的”,它回答,“命令号 3”。 “嗨,对象,请你执行 3 号命令”。 “当然,这是结果”。
来自 Visual Basic 概念(帮助的一部分)
您可以通过优化 Visual Basic 解析对象引用的方式使您的 Visual Basic 应用程序运行得更快。 Visual Basic 处理对象引用的速度可能受以下因素影响:
ActiveX 组件是否已实现为进程内服务器或进程外服务器。
对象引用是早期绑定还是后期绑定。通常,如果一个组件已作为可执行文件(.exe 文件)的一部分实现,则它是一个进程外服务器并在其自己的进程中运行。如果它被实现为动态链接库,则它是一个进程内服务器,并与客户端应用程序在同一进程中运行。
使用进程内服务器的应用程序通常比使用进程外服务器的应用程序运行得更快,因为应用程序不必跨越进程边界来使用对象的属性、方法和事件。有关进程内和进程外服务器的更多信息,请参阅“进程内和进程外服务器”。
如果对象引用使用声明为特定类的变量的对象变量,则它们是早期绑定的。如果对象引用使用声明为通用 Object 类的变量的对象变量,则对象引用是后期绑定的。使用早期绑定变量的对象引用通常比使用后期绑定变量的对象引用运行得更快。
Excel 特定
查看来自 Microsoft 人员的此链接。这是特定于 excel 而不是 VBA。自动计算和其他计算选项/屏幕更新等。
http://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/
【讨论】:
在 vba 中使用变体对性能不利吗? - 是的!
Variant 应尽可能避免。 (当然有一些合法用途)
【讨论】: