VBA早期绑定与后期绑定-现实生活中的性能差异 [英] VBA Early vs Late binding - real life performance differences

查看:254
本文介绍了VBA早期绑定与后期绑定-现实生活中的性能差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我正在编写一个健壮的Word宏,该宏将在几台不同的计算机上的广泛Word中使用.
我在许多VBA专家论坛上都说过,早期绑定总是比后期绑定更可取,因为它们在性能上要好得多.

从我的逻辑来看,但是-除非令人信服地证明了好处-否则,就可用性而言,恰恰相反的情况适用,因为我不希望确保在所有可能运行的机器上打勾这些lib-references的痛苦. >
我已经尝试过ThisWorkbook.VBProject.References.AddFromGUID "{420B2830-E718-11CF-893D-00A0C9054228}", 1, 0.它将以编程方式添加引用,但随后需要在计算机上启用安全性信任以进行代码操作.
因此,我随后进行了一项测试,以比较1000次早期和晚期绑定字典操作的运行情况.我还尝试了其他测试设置,例如ScreenUpdating,DoEvents,Debug.Print,以查看每种设置对性能的影响.
到目前为止,我看到的是,早期绑定与后期绑定本身在任何设置中均没有可测量的性能差异(任何运行之间的随机波动为10%).
VBA Guru-s我对您对这个故事的了解感兴趣,那么为什么我应该使用Early binding,或者它在REAL LIFE LIFE USAGE中确实具有这种优势?

我的TestCode是这样的:


I'm writing a robust Word macro that will be used on wide range of Words on several different machines.
I have red on many expert VBA forums, that early binding is always preferred to late binding, as being far superior in performance, etc.

For my logic it feels so however -unless benefits are proven convincingly-, that the exact opposite applies in terms of usability, because i don't want the pain of assuring those lib-references ticked on all machines it might run on.

I have experimented with ThisWorkbook.VBProject.References.AddFromGUID "{420B2830-E718-11CF-893D-00A0C9054228}", 1, 0. It would add the reference programatically, BUT it then needs the Security trust to be enabled on the machine for code manipulation.
So then i have set up a test to compare 1000 runs of early vs late bindt Dictionary operations. I have played around with other test settings also, like ScreenUpdating, DoEvents, Debug.Print to see the performance impact of each.
So far what i see is that Early vs Late binding itself had NO measurable performance difference in any setup (except a 10% random fluctuation between any runs).
VBA Guru-s I'm interested in your catch on this story, why should i use Early binding then, or is it really such an advantage in REAL LIFE USAGE.

My TestCode was this:

Sub HeadingDefinitionWords_test()
    Application.ScreenUpdating = False
    Dim tm As Long
    tm = timeGetTime
    Dim DefinitionRangeBackup As Range, DefinitionRange As Range
    Dim kEy As Variant, i As Long, k As Integer
    Dim TempList As Object: Set TempList = CreateObject("Scripting.Dictionary")
    'Dim TempList As Scripting.Dictionary: Set TempList = New Scripting.Dictionary
    For i = 1 To 1000
    'Call HeadingDefinitionWords(Selection.Range.Duplicate, TempList)
    '''
         Set DefinitionRange = Selection.Range.Duplicate
         Set DefinitionRangeBackup = DefinitionRange.Duplicate
         '-
            With DefinitionRange.Find: .ClearFormatting: .Text = "([a-z])([A-Z])"
                .Forward = True: .Wrap = wdFindStop: .Format = False: .MatchCase = False: .MatchWholeWord = False: .MatchAllWordForms = False
                .MatchSoundsLike = False: .MatchWildcards = True
            End With
        '-
            With DefinitionRange: While .Find.Execute And .InRange(DefinitionRangeBackup)
            '-
                .Expand Unit:=wdWord
            '-
                If Not TempList.Exists(Trim(DefinitionRange.Text)) Then TempList.Add Trim(DefinitionRange.Text), Trim(DefinitionRange.Text)
            '-
                DefinitionRange.Collapse wdCollapseEnd
            Wend: End With

        '''
        For Each kEy In TempList
            'Debug.Print kEy
            If k = 50 Then
                'Debug.Print k
                k = 1
            Else
                k = k + 1
            End If
            'DoEvents
        Next

    Next

    Dim tma As Long
    tma = timeGetTime
    Debug.Print tma - tm

    Application.ScreenUpdating = True
End Sub

推荐答案

不确定是否应该作为答案,但是,嘿,

Not sure this should go as answer but hey,

早期绑定是开发工作(速度和智能感知)的首选.出于您提到的确切原因,后期绑定经常用于分发.后期绑定在生产中要安全得多,除非您绝对可以100%确定用户的设置.

Early binding is preferred for development work (speed and intellisense). Late binding is frequently used for distribution for exactly the reasons you mention. Far safer to go with Late binding in production unless you can be absolutely 100% certain of your users set-ups.

要引用 Word MVP网站

早期绑定的优势

您的代码将运行得更快,因为它们都可以预先编译.对于后期绑定,实际上必须在运行时编译与您声明为对象的应用程序相关的代码.

Your code will run considerably faster, because it can all be compiled up front. With late binding, the code relating to an application you declared as an object has to, in effect, be compiled as it runs.

因为所有代码都可以预先编译,所以调试要容易得多–选择Debug + Compile,编译器将能够发现如果使用后期绑定则可能遗漏的语法错误.

Because your code can all be compiled up front, debugging is far easier – select Debug + Compile, and the compiler will be able to spot syntax errors which would have been missed had you used late binding.

您在项目中拥有对智能的完全访问权限(键入一个关键字和一个点以获取该关键字支持的属性和方法的弹出列表,选择一个即可插入它;键入一个关键字并按F1键启动帮助"主题在该关键字上).

You have full access in your project to intellisense (type a keyword and a dot to get a popup list of properties and methods supported by that keyword, select one to insert it; type a keyword and press F1 to launch the Help topic on that keyword).

您可以通过对象浏览器和VBA帮助完全访问应用程序的对象模型.

You have full access to the application's object model via the Object Browser and VBA Help.

您可以访问应用程序的内置常量.例如,如果要从Excel自动化Word,则可以使用:

You have access to the application's built-in constants. For instance, if you are automating Word from Excel, you can use:

Dim objWord As Word.Application 
Set objWord = New Word.Application 

With objWord 
    .Visible = True 
    .Activate 
    .WindowState = wdWindowStateMaximize 
    .Documents.Open ("c:\temp\temp.doc") 
End With 

此外,当您键入

.WindowState =

您将获得一个受支持的常量的弹出列表,只需从列表中选择wdWindowStateMaximize.

you'll get a pop-up list of the supported constants, and can simply pick wdWindowStateMaximize from the list.

如果您使用了后期绑定,则需要使用:

If you used late binding, you would need to use:

.WindowState = 1

..,您需要知道(通过在Word的对象浏览器中查找)常数"wdWindowStateMaximize"的值恰好是1.

.. and you would need to know (by looking it up in Word's Object Browser) that the value of the constant "wdWindowStateMaximize" happens to be 1.

所有这些使使用早期绑定的编程比使用后期绑定的编程容易得多.

All this makes programming using early binding immeasurably easier than using late binding.

后期绑定的优势

主要优点是,使用后期绑定的代码更肯定是与版本无关的

The main advantage is that code which uses late binding is more certain to be version-independent

如果在Word 97项目中将引用设置为"Microsoft Excel 8.0对象库",则该项目将在装有Office 2000的计算机上运行确定. Word 2000会将引用动态更改为"Microsoft Excel 9.0对象库".

If you set a reference in a Word 97 project to "Microsoft Excel 8.0 Object Library", then the project will run OK on a machine which has Office 2000 installed. Word 2000 changes the reference on the fly to the "Microsoft Excel 9.0 Object Library".

但是正如他们所说的,YMMV.在某些情况下已发现问题.例如,如果在安装了Office 2000的计算机上运行包含对Excel 8.0对象库的引用的Word 97项目,它将运行OK,但是除非您保存该项目,否则偶尔会出现无法打开宏存储"错误.在Word 2000中.如果确实将其保存在Word 2000中,则引用将更改为Excel 9.0对象库.

But as they famously say, YMMV. Problems have been found in certain circumstances. For instance, if you run a Word 97 project containing a reference to the Excel 8.0 object library on a machine with Office 2000 installed, it will run OK, but you may get the occasional "cannot open macro storage" error unless you save the project in Word 2000. If you do save it in Word 2000, the reference will change to the Excel 9.0 object library.

因此,如果您使用早期绑定并支持混合环境,那么尽管存在维护开销,但是创建单独的Word 97和Word 2000版本的加载项可能是最安全的.

So if you use early binding and support a mixed environment, it may be safest to create separate Word 97 and Word 2000 versions of your addins, despite the maintenance overhead.

项目包含的引用越多,文件大小越大,编译所需的时间越长.

The more references your project contains, the larger the file size and the longer it takes to compile.

某些编程环境不允许您创建对另一个应用程序的引用.

Some programming environments don't allow you to create references to another application.

如果您真的想开始研究COM对象,则v-tables之类的对象可以从以下参考文献开始:

If you really want to start delving into COM objects, v-tables and the like maybe start with the following reference:

参考文献:

  1. Microsoft Blurb: 查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆