A Comparison of Early and Late Binding

I'm always going on about how I prefer late binding over early binding. So does that mean my code comes out slower than yours?

I found a nice article that actually checks whether late binding is slower than early binding. It found that late binding was only trivially slower. But you know I wouldn't be writing this if I didn't do some tests of my own anyway.

A new Timer function

That article mentioned a more accurate timing function than the one I'd been using (Timer). After some research, I decided to implement it myself. I won't be updating the previous tests, but from now on I'll be using the timeGetTime API. This makes my tests only slightly less unscientific.

To use it you simply add this declaration at the top of a module as follows:

Public Declare Function timeGetTime Lib "winmm.dll" () As Long

Early and Late Binding with Outlook

We'll start with Outlook. We need to create two Outlook.Application objects, one early and one late bound. First I (ugh) set a reference to the Outlook Object Library:

Outlook Object Library Reference

Now we'll need to loop through the creation of various Outlook objects. I included the creation of the Outlook.Application object into the overall time.

Sub TestEarlyLateBindingOutlook()

  Dim i As Long
  Dim startTimeEarly As Long
  Dim endTimeEarly As Long
  Dim startTimeLate As Long
  Dim endTimeLate As Long
  Dim msg As String
  Dim olAppEarly As Outlook.Application
  Dim olAppLate As Object  ' Outlook.Application
  Dim msgEarly As Outlook.MailItem
  Dim msgLate As Object  ' Outlook.MailItem

  Const numberofloops As Long = 1000

  ' use early binding
  startTimeEarly = timeGetTime
  Set olAppEarly = CreateObject("Outlook.Application")
  For i = 1 To numberofloops
    Debug.Print olAppEarly.Version
    Set msgEarly = olAppEarly.CreateItem(olMailItem)
  Next i
  endTimeEarly = timeGetTime

  ' destroy object so late binding doesn't have 
  ' an existing object to reference
  Set olAppEarly = Nothing
  Set msgEarly = Nothing

  ' use late binding
  startTimeLate = timeGetTime
  Set olAppLate = CreateObject("Outlook.Application")
  For i = 1 To numberofloops
    Debug.Print olAppLate.Version
    Set msgLate = olAppLate.CreateItem(0)
  Next i
  endTimeLate = timeGetTime

  msg = "Using Early binding: " & _
        (endTimeEarly - startTimeEarly) / 1000 & " seconds" & vbCrLf
  msg = msg & "Using Late binding: " & _
        (endTimeLate - startTimeLate) / 1000 & " seconds" & vbCrLf
  MsgBox msg

End Sub

Because Outlook is a single-instance application, to prevent the late bound code from grabbing the existing instance, we destroy the object before doing our late bound test.

Results

We'll start with 1,000 iterations.

Early vs Late Binding in Outlook, 1,000 iterations

The late bound Outlook object is running slightly faster. Let's continue to 2,000 iterations:

Early vs Late Binding in Outlook, 2,000 iterations

The early bound Outlook object is running even slower now. At 5,000 iterations, the early bound object is about 2 seconds slower:

Early vs Late Binding in Outlook, 5,000 iterations

Finally, at 7,500 iterations, early binding is just over 11 seconds while late binding is just under eight:

Early vs Late Binding in Outlook, 7,500 iterations

I would love to hear that I'm doing this wrong, but it looks like late binding is faster. Ha! Take that, all you early binders!

Early and Late Binding with Access

Now I'll try to do this with Access. We'll create two databases, then read some simple properties. Based on the previous example, my assumption is that late binding will be faster than early binding.

As usual, we first manually set a reference to the Access Object Library:

Access Object Library Reference

Sub TestEarlyLateBindingAccess()

  Dim i As Long
  Dim startTimeEarly As Long
  Dim endTimeEarly As Long
  Dim startTimeLate As Long
  Dim endTimeLate As Long
  Dim msg As String
  Dim accAppEarly As Access.Application
  Dim accAppLate As Object  ' Access.Application

  Const numberofloops As Long = 1000

  On Error Resume Next
  Kill "C:\my_early_bound_database.mdb"
  Kill "C:\my_late_bound_database.mdb"
  On Error GoTo 0

  ' use early binding
  startTimeEarly = timeGetTime
  Set accAppEarly = CreateObject("Access.Application")
  accAppEarly.DBEngine.CreateDatabase _
    "C:\my_early_bound_database.mdb", ";LANGID=0x0409;CP=1252;COUNTRY=0"
  For i = 1 To numberofloops
    Debug.Print accAppEarly.Version
    Debug.Print accAppEarly.ProductCode
  Next i
  endTimeEarly = timeGetTime

  ' use late binding
  startTimeLate = timeGetTime
  Set accAppLate = CreateObject("Access.Application")
  accAppLate.DBEngine.CreateDatabase _
    "C:\my_late_bound_database.mdb", ";LANGID=0x0409;CP=1252;COUNTRY=0"
  For i = 1 To numberofloops
    Debug.Print accAppLate.Version
    Debug.Print accAppLate.ProductCode
  Next i
  endTimeLate = timeGetTime

  msg = "Using Early binding: " & _
        (endTimeEarly - startTimeEarly) / 1000 & " seconds" & vbCrLf
  msg = msg & "Using Late binding: " & _
        (endTimeLate - startTimeLate) / 1000 & _
        " seconds" & vbCrLf
  MsgBox msg

End Sub

Results

First we'll start out with 1,000 iterations. It looks like late binding is actually slower!

Early vs Late Binding in Access, 1,000 iterations

At 2,000 iterations late binding is still slower:

Early vs Late Binding in Access, 2,000 iterations

At 5,000 iterations, late binding looks like it is getting even slower. It takes 2.2 seconds for late binding to create a database and read some simple properties, while early binding is taking only 1.3 seconds.

Early vs Late Binding in Access, 5,000 iterations

Finally, at 7,500 iterations, it is still barely noticeable but early binding is definitely faster:

Early vs Late Binding in Access, 7,500 iterations

Conclusion

Although I will be sticking with late binding, there are clearly times when early binding is faster. I feel validated using late binding in my code but I still don't understand why it was faster with Outlook than with Access.

One lesson the article reminds us is that if you have to use an object's methods or properties in a loop, create the object outside the loop. If you have a function that needs an object, create the object in the calling procedure and pass it to the function. This way, if you need to call the function repeatedly, the object is only ever created once, minimizing the late binding time penalty (if any).

An example of this may be found on the MSXML Object Library page. The GetResponse function takes an existing XMLHTTP object as a parameter, so you would need to create this object in the calling function. This way, you can loop the GetResponse function, creating the XMLHTTP object only once and reusing it through each iteration of the loop.

Read more about binding at the revised Early and Late Binding page.

About JP

I'm just an average guy who writes VBA code for a living. This is my personal blog. Excel and Outlook are my thing, with a sprinkle of Access and Word here and there. Follow this space to learn more about VBA. Keep Reading »



Share This Article:

Share and bookmark this articledelicious buttonfacebook buttonlinkedin buttonstumbleupon buttontwitter button

comment bubble 5 Comment(s) on A Comparison of Early and Late Binding:

  1. Hi,
    Did you have your Outlook open when you started the test? As you state "Outlook is a single-instance application", so if you didn't then the early bound version would have had to actually create – ie start up Outlook, whilst the latebound version just had to "get" the object.
    You'd need olAppEarly.quit to prevent that.

    That said, a linear trend line on your results still suggest that late binding is a third quicker than early binding for outlook and if the above was the issue it wouldn't. But take this with a pinch of salt as well as the linear trend also gives a negative overhead forcreating the object for both early & late binding!

    • Did you have your Outlook open when you started the test?

      I'm not sure it matters. Either way, both sets of code have to get an instance of Outlook.Application. Whether Outlook happens to already be open or not would simply raise or lower the overall completion time of each loop.

      You'd need olAppEarly.quit to prevent that

      I specifically addressed that in the code.

  2. This may be a dumb question, but essentially the only difference between early binding and late binding is that early binding sets a reference to the Object Library manually before running any code?

This article is closed to new comments. Why?
Excel School