在 vba 中使用变体对性能不利吗?
Is using variants in vba bad for performance?
我想标题很简单,将变量声明为变体而不是特定数据类型对 VBA 中的性能有什么影响?
也许是因为我没有那么多编程经验,但直觉上它应该会降低性能,因为计算机必须检查分配了哪种数据类型,然后将变体更改为分配的数据类型,而不是立即分配值给它。我没能找到这方面的文献。
在 vba 中使用变体是否会影响性能? - 是的!
Variant
应尽可能避免。 (当然有一些合法用途)
视情况而定。变体比原生类型慢,但在大多数程序中,这根本无关紧要。大多数宏都很小,并且在 运行 时编译,差异可能只有几微秒,您无法察觉。
变体各有优势,我喜欢它们。
所以这取决于你在做什么。如果你的程序运行s在一个blink的眼睛里,避免变体没有任何优势。如果需要时间,请强烈键入您的变量(并正确声明对象 - 见下文)。
如果性能是一个问题,除此之外我还会在下面提到其他事情。
一般问题
设置属性或调用方法时,每一个都是CPU中的一个函数调用。这意味着堆栈设置开销。函数调用比内联代码慢。出于同样的原因,在 VBA 中使用循环而不是函数。
F 或一开始不要一遍又一遍地指定所有这些属性。除非你改变它们,否则它们不会改变。
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
阅读属性
不要重新读取不会更改的属性,尤其是在进程外或后期绑定时。将它们放入变量中。
对象类型
这里有两个概念 - 进程内或进程外以及早期或晚期绑定。
exe文件连接到进程外。所有调用都通过 RPC(一种网络协议)进行编组。 Dll 文件正在处理中,函数调用直接跳转。
早期绑定是 set x = objecttype
。编写程序时会查找函数。在执行时,程序被硬编码为跳转到存储在该函数的 vtable 中的地址。
已设置延迟绑定 x = createobject("objecttype")
。每个函数调用都是这样的。 "Hi object do you have a print command"。 "Yes",它回复,"command number 3"。 "Hi object can you please do command number 3"。 "Sure, here's the result".
来自 Visual Basic 概念(帮助的一部分)
您可以通过优化 Visual Basic 解析对象引用的方式使您的 Visual Basic 应用程序 运行 更快。 Visual Basic 处理对象引用的速度受以下因素影响:
是否将 ActiveX 组件实现为进程内服务器或进程外服务器。
对象引用是早期绑定还是后期绑定。一般来说,如果一个组件已经作为可执行文件(.exe 文件)的一部分实现,那么它就是一个进程外服务器,并且 运行s 在它自己的进程中。如果它已作为动态-link 库实现,则它是一个进程内服务器并且 运行 与客户端应用程序在同一进程中。
使用进程内服务器的应用程序通常 运行 比使用进程外服务器的应用程序更快,因为应用程序不必跨越进程边界来使用对象的属性、方法和事件.有关进程内和进程外服务器的详细信息,请参阅 "In-Process and Out-of-Process Servers."
如果对象引用使用声明为特定 class 变量的对象变量,则它们是早期绑定的。如果对象引用使用声明为通用对象 class 变量的对象变量,则对象引用是后期绑定的。使用早期绑定变量的对象引用通常 运行 比使用后期绑定变量的对象引用更快。
Excel 具体
从 Microsoft 人员那里看到这个 link。这是 excel 特定的,而不是 VBA。 Autocalc 和其他计算 options/screenupdating 等
http://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/
.
我想标题很简单,将变量声明为变体而不是特定数据类型对 VBA 中的性能有什么影响?
也许是因为我没有那么多编程经验,但直觉上它应该会降低性能,因为计算机必须检查分配了哪种数据类型,然后将变体更改为分配的数据类型,而不是立即分配值给它。我没能找到这方面的文献。
在 vba 中使用变体是否会影响性能? - 是的!
Variant
应尽可能避免。 (当然有一些合法用途)
视情况而定。变体比原生类型慢,但在大多数程序中,这根本无关紧要。大多数宏都很小,并且在 运行 时编译,差异可能只有几微秒,您无法察觉。
变体各有优势,我喜欢它们。
所以这取决于你在做什么。如果你的程序运行s在一个blink的眼睛里,避免变体没有任何优势。如果需要时间,请强烈键入您的变量(并正确声明对象 - 见下文)。
如果性能是一个问题,除此之外我还会在下面提到其他事情。
一般问题
设置属性或调用方法时,每一个都是CPU中的一个函数调用。这意味着堆栈设置开销。函数调用比内联代码慢。出于同样的原因,在 VBA 中使用循环而不是函数。
F 或一开始不要一遍又一遍地指定所有这些属性。除非你改变它们,否则它们不会改变。
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
阅读属性
不要重新读取不会更改的属性,尤其是在进程外或后期绑定时。将它们放入变量中。
对象类型
这里有两个概念 - 进程内或进程外以及早期或晚期绑定。
exe文件连接到进程外。所有调用都通过 RPC(一种网络协议)进行编组。 Dll 文件正在处理中,函数调用直接跳转。
早期绑定是 set x = objecttype
。编写程序时会查找函数。在执行时,程序被硬编码为跳转到存储在该函数的 vtable 中的地址。
已设置延迟绑定 x = createobject("objecttype")
。每个函数调用都是这样的。 "Hi object do you have a print command"。 "Yes",它回复,"command number 3"。 "Hi object can you please do command number 3"。 "Sure, here's the result".
来自 Visual Basic 概念(帮助的一部分)
您可以通过优化 Visual Basic 解析对象引用的方式使您的 Visual Basic 应用程序 运行 更快。 Visual Basic 处理对象引用的速度受以下因素影响:
是否将 ActiveX 组件实现为进程内服务器或进程外服务器。
对象引用是早期绑定还是后期绑定。一般来说,如果一个组件已经作为可执行文件(.exe 文件)的一部分实现,那么它就是一个进程外服务器,并且 运行s 在它自己的进程中。如果它已作为动态-link 库实现,则它是一个进程内服务器并且 运行 与客户端应用程序在同一进程中。
使用进程内服务器的应用程序通常 运行 比使用进程外服务器的应用程序更快,因为应用程序不必跨越进程边界来使用对象的属性、方法和事件.有关进程内和进程外服务器的详细信息,请参阅 "In-Process and Out-of-Process Servers."
如果对象引用使用声明为特定 class 变量的对象变量,则它们是早期绑定的。如果对象引用使用声明为通用对象 class 变量的对象变量,则对象引用是后期绑定的。使用早期绑定变量的对象引用通常 运行 比使用后期绑定变量的对象引用更快。
Excel 具体
从 Microsoft 人员那里看到这个 link。这是 excel 特定的,而不是 VBA。 Autocalc 和其他计算 options/screenupdating 等
http://blogs.office.com/2009/03/12/excel-vba-performance-coding-best-practices/