Late Binding vs Early Binding in out-of-process servers
Author |
Message |
Neil McKechni #1 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Help! Can anyone please explain what is happening in this example? I have a group of course delegates who are confused and I cannot enlighten them! Most people will tell you that late binding is slower than early binding when calling ActiveX servers (DLL or EXE). However, I have a demo program where this doesn't happen. The server in this example is out-of-process (exe) and runs on the same machine as the client. 'Adder' is a property of AxServer.Application which returns a reference to an 'Adder' object. This, in turn, has a method called 'AddNumber'. Late Binding Example ~~~~~~~~~~~~~~~~~ Dim o as Object Set o = new AxServer.Application For i = 1 to MaxCount o.Adder.AddNumber i Next Early Binding Example ~~~~~~~~~~~~~~~~~ Dim o as AxServer.Application For i = 1 to MaxCount o.Adder.AddNumber i Next The Late binding example takes about 28 seconds and the early bound one takes about 42 seconds - I would have expected the opposite. NB if a WITH construct is used outside the loop, then the early binding example is faster than the late one, as expected. Can anyone enlighten me to the reason for this? Neil McKechnie Microlink Associates Ltd
|
Mon, 05 Feb 2001 03:00:00 GMT |
|
 |
Joel Shepher #2 / 11
|
 Late Binding vs Early Binding in out-of-process servers
First, something is missing from your early-binding code example. Is the _actual_ code this: Dim o as AxServer.Application Set o = New AxServer.Application ....or this... Dim o as New AxServer.Application ^^^ If it's the latter, that _may_ explain the speed difference. If you Dim something "As New", everytime you reference the object, VB has to check to see if the object has been instantiated, and instantiate it if necessary. I don't know what all is involved in that checking, but if it includes checking that the existing reference is valid, that check may eat up a significant number of CPU cycles. In general, the first case (Dim followed by Set = New) will give better performance. So ... which is it really? Quote:
> Help! Can anyone please explain what is happening in this example? I have > a group of course delegates who are confused and I cannot enlighten them! > Most people will tell you that late binding is slower than early binding > when calling ActiveX servers (DLL or EXE). However, I have a demo program > where this doesn't happen. The server in this example is out-of-process > (exe) and runs on the same machine as the client. 'Adder' is a property of > AxServer.Application which returns a reference to an 'Adder' object. This, > in turn, has a method called 'AddNumber'. > Late Binding Example > ~~~~~~~~~~~~~~~~~ > Dim o as Object > Set o = new AxServer.Application > For i = 1 to MaxCount > o.Adder.AddNumber i > Next > Early Binding Example > ~~~~~~~~~~~~~~~~~ > Dim o as AxServer.Application > For i = 1 to MaxCount > o.Adder.AddNumber i > Next > The Late binding example takes about 28 seconds and the early bound one > takes about 42 seconds - I would have expected the opposite. NB if a WITH > construct is used outside the loop, then the early binding example is faster > than the late one, as expected. > Can anyone enlighten me to the reason for this? > Neil McKechnie > Microlink Associates Ltd
|
Mon, 05 Feb 2001 03:00:00 GMT |
|
 |
Gerald Gardne #3 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Actually the use of: Dim O as New AxServer.Application actually only costs less than 1% of processing time in this example. When the Set O = New AxServer.Application is used the "problem" still exists. In cross-process calls the main hit is in the cross-process marshalling of data. Even in an in-process call the "Set" method is only about 3.5% faster (in this example). Gerald Gardner Quote:
>First, something is missing from your early-binding code example. Is the >_actual_ code this: > Dim o as AxServer.Application > Set o = New AxServer.Application >....or this... > Dim o as New AxServer.Application > ^^^ >If it's the latter, that _may_ explain the speed difference. If you Dim >something "As New", everytime you reference the object, VB has to check >to see if the object has been instantiated, and instantiate it if >necessary. I don't know what all is involved in that checking, but if it >includes checking that the existing reference is valid, that check may >eat up a significant number of CPU cycles. In general, the first case >(Dim followed by Set = New) will give better performance. >So ... which is it really?
>> Help! Can anyone please explain what is happening in this example? I have >> a group of course delegates who are confused and I cannot enlighten them! >> Most people will tell you that late binding is slower than early binding >> when calling ActiveX servers (DLL or EXE). However, I have a demo program >> where this doesn't happen. The server in this example is out-of-process >> (exe) and runs on the same machine as the client. 'Adder' is a property of >> AxServer.Application which returns a reference to an 'Adder' object. This, >> in turn, has a method called 'AddNumber'. >> Late Binding Example >> ~~~~~~~~~~~~~~~~~ >> Dim o as Object >> Set o = new AxServer.Application >> For i = 1 to MaxCount >> o.Adder.AddNumber i >> Next >> Early Binding Example >> ~~~~~~~~~~~~~~~~~ >> Dim o as AxServer.Application >> For i = 1 to MaxCount >> o.Adder.AddNumber i >> Next >> The Late binding example takes about 28 seconds and the early bound one >> takes about 42 seconds - I would have expected the opposite. NB if a WITH >> construct is used outside the loop, then the early binding example is faster >> than the late one, as expected. >> Can anyone enlighten me to the reason for this? >> Neil McKechnie >> Microlink Associates Ltd
|
Tue, 06 Feb 2001 03:00:00 GMT |
|
 |
Gerald Gardne #4 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Might I display my ignorance of cross-process marshalling by making a wild guess? Could it be possible that the late bound out-of-process call passses the entire ".Adder.AddNumber i" operation out of process in a single call while the early bound call may actually be accomplished in two out-of-process calls, one to return the "Adder" object and a second to call the "AddNumber" method? I would expect 2 out-of-process calls to an early bound object to be slower than a single out-of-process call to a late-bound object. Even stranger, try this - insert the lines below just before the "For" loop: Dim o1 As Object Set o1 = New AxServer.CApplication dblTimer = Timer Dim Adder1 As Object '*** insert line Set Adder1 = o1.Adder '*** insert line For i = 1 To MaxCount o1.Adder.AddNumber i Next Dim o2 As AxServer.CApplication Set o2 = New AxServer.CApplication Dim Adder2 As AxServer.CAdder '*** insert line Set Adder2 = o2.Adder '*** insert line For i = 1 To MaxCount o2.Adder.AddNumber i Next This also seems to "fix" the problem, without using the "With" construct! ...weird... Gerald Gardner
Quote: >Help! Can anyone please explain what is happening in this example? I have >a group of course delegates who are confused and I cannot enlighten them! >Most people will tell you that late binding is slower than early binding >when calling ActiveX servers (DLL or EXE). However, I have a demo program >where this doesn't happen. The server in this example is out-of-process >(exe) and runs on the same machine as the client. 'Adder' is a property of >AxServer.Application which returns a reference to an 'Adder' object. This, >in turn, has a method called 'AddNumber'. >Late Binding Example >~~~~~~~~~~~~~~~~~ >Dim o as Object >Set o = new AxServer.Application >For i = 1 to MaxCount > o.Adder.AddNumber i >Next >Early Binding Example >~~~~~~~~~~~~~~~~~ >Dim o as AxServer.Application >For i = 1 to MaxCount > o.Adder.AddNumber i >Next >The Late binding example takes about 28 seconds and the early bound one >takes about 42 seconds - I would have expected the opposite. NB if a WITH >construct is used outside the loop, then the early binding example is faster >than the late one, as expected. >Can anyone enlighten me to the reason for this? >Neil McKechnie >Microlink Associates Ltd
|
Tue, 06 Feb 2001 03:00:00 GMT |
|
 |
Joel Shepher #5 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Quote:
> Actually the use of: > Dim O as New AxServer.Application > actually only costs less than 1% of processing time in this example. When > the > Set O = New AxServer.Application > is used the "problem" still exists. In cross-process calls the main hit is > in the cross-process marshalling of data. Even in an in-process call the > "Set" method is only about 3.5% faster (in this example). > Gerald Gardner
So does this imply that VB doesn't actually validate an object reference when it is declared Dim...As New? I wouldn't be surprised; I'm just curious.
|
Tue, 06 Feb 2001 03:00:00 GMT |
|
 |
Gerald Gardne #6 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Quote:
>> Actually the use of: >> Dim O as New AxServer.Application >> actually only costs less than 1% of processing time in this example. When >> the >> Set O = New AxServer.Application >> is used the "problem" still exists. In cross-process calls the main hit is >> in the cross-process marshalling of data. Even in an in-process call the >> "Set" method is only about 3.5% faster (in this example). >> Gerald Gardner >So does this imply that VB doesn't actually validate an object reference >when it is declared Dim...As New? I wouldn't be surprised; I'm just >curious.
Oh, I believe it does, and by default I always use the: Dim X as CObjClass Set X = New CObjectClass method, it's just that the overhead seems to be fairly negligible. Me I'll take the 4% improvement.
|
Thu, 08 Feb 2001 03:00:00 GMT |
|
 |
VBDi #7 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Quote: >If you Dim >something "As New", everytime you reference the object, VB has to check >to see if the object has been instantiated
That check must always be performed, since you can set the variable to Nothing or something else everywhere in code. I suspect that the check and linkage for late bound objects is done only with the first call, and afterwards is handled like with early binding, until the object variable is changed to a different object. DoDi
|
Fri, 09 Feb 2001 03:00:00 GMT |
|
 |
Gerald Gardne #8 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Quote:
>>If you Dim >>something "As New", everytime you reference the object, VB has to check >>to see if the object has been instantiated >That check must always be performed, since you can set the variable to Nothing >or something else everywhere in code. >I suspect that the check and linkage for late bound objects is done only with >the first call, and afterwards is handled like with early binding, until the >object variable is changed to a different object. >DoDi
The check is not whether the object is nothing or a valid object reference but whether the object has been created. Declaring the object as "new" does not create the object, the first reference to the object is then it is created. So with each reference to the object there is a check to see "Has this 'new' object been created? if not create it." Late bound objects use the IDispatch interface where function entry points have to be resolved and syntax and type checking are performed with each call. Calls to early bound (in-process) objects are almost as fast as direct DLL function calls.
|
Fri, 09 Feb 2001 03:00:00 GMT |
|
 |
Neil McKechni #9 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Thanks to all who pointed out that I had missed one line in transcribing the program. Thanks also to Bruno Paris who has made some constructive suggestions. I am still investigating this by various means (including network trace of DCOM calls), and will post the reason if I can find it. In summary, the results from the test are: EXE server, Early Binding: 42 sec EXE server, Late Binding: 28 sec DLL server, Early Binding: 90 msec DLL server, Late Binding: 1,130 msec The figures for a DLL server are to be expected, as late binding should cause extra overheads, but the figures for the EXE server are not what we expected. Anyone who can explain it please let me know. Neil.
Quote: >Help! Can anyone please explain what is happening in this example? I have >a group of course delegates who are confused and I cannot enlighten them! >Most people will tell you that late binding is slower than early binding >when calling ActiveX servers (DLL or EXE). However, I have a demo program >where this doesn't happen. The server in this example is out-of-process >(exe) and runs on the same machine as the client. 'Adder' is a property of >AxServer.Application which returns a reference to an 'Adder' object. This, >in turn, has a method called 'AddNumber'. >Late Binding Example >~~~~~~~~~~~~~~~~~ >Dim o as Object >Set o = new AxServer.Application >For i = 1 to MaxCount > o.Adder.AddNumber i >Next >Early Binding Example >~~~~~~~~~~~~~~~~~ >Dim o as AxServer.Application
Set o = new AxServer.Application ' This line missing in original post... Quote: >For i = 1 to MaxCount > o.Adder.AddNumber i >Next >The Late binding example takes about 28 seconds and the early bound one >takes about 42 seconds - I would have expected the opposite. NB if a WITH >construct is used outside the loop, then the early binding example is faster >than the late one, as expected. >Can anyone enlighten me to the reason for this? >Neil McKechnie >Microlink Associates Ltd
|
Fri, 09 Feb 2001 03:00:00 GMT |
|
 |
Gerald Gardne #10 / 11
|
 Late Binding vs Early Binding in out-of-process servers
Mathew, Quite interesting, I was unaware that an object variable declared with "new" would allways be created (I allways use the "set .. = new .." method anyway). But I still believe my point is valid. The check performed when using the "dim .. new" v. "set .. new" is different, and using "dim .. new" is more expensive. Quote: >Matthew Wills wrote via e-mail: >Gerald, >> The check is not whether the object is nothing or a valid object reference >> but whether the object has been created. >Incorrect. >> Declaring the object as "new" does >> not create the object, the first reference to the object is then it is >> created. >Almost true. Change it to read: >Declaring the object as "new" does not create the object, it simply >makes sure that all references to the object are using a valid object >reference. In short, it creates the object whenever the object is >Nothing and you reference the object. >> So with each reference to the object there is a check to see "Has >> this 'new' object been created? if not create it." >Incorrect. When you set the object to nothing, and then reference it >again, it will be recreated (this doesn't make sense if it is checking >whether or not it has been created, because it has been created, and it >still recreates it). >Check out: > http://home.earthlink.net/~butlerbob/vb/begin/dimnew.htm >for more info. >Matthew
|
Sat, 10 Feb 2001 03:00:00 GMT |
|
 |
Joel Shepher #11 / 11
|
 Late Binding vs Early Binding in out-of-process servers
How is Adder declared? In particular, is the argument passed ByVal or ByRef? ByVal will be faster with out-of-process servers, since COM is smart enough to know that the value doesn't have to be marshalled back to the caller. When you pass a value ByRef, COM has to marshal the value over to the server, and then marshal it back to the caller, since it's possible that the server modified the value, and the caller was depending on this. Since ByVal parameters can't be modified (from the client's point of view), they need only be marshaled to the server, but not back to the client. Quote:
> Thanks to all who pointed out that I had missed one line in transcribing the > program. Thanks also to Bruno Paris who has made some constructive > suggestions. I am still investigating this by various means (including > network trace of DCOM calls), and will post the reason if I can find it. > In summary, the results from the test are: > EXE server, Early Binding: 42 sec > EXE server, Late Binding: 28 sec > DLL server, Early Binding: 90 msec > DLL server, Late Binding: 1,130 msec > The figures for a DLL server are to be expected, as late binding should > cause extra overheads, but the figures for the EXE server are not what we > expected. > Anyone who can explain it please let me know. > Neil.
> >Help! Can anyone please explain what is happening in this example? I have > >a group of course delegates who are confused and I cannot enlighten them! > >Most people will tell you that late binding is slower than early binding > >when calling ActiveX servers (DLL or EXE). However, I have a demo program > >where this doesn't happen. The server in this example is out-of-process > >(exe) and runs on the same machine as the client. 'Adder' is a property of > >AxServer.Application which returns a reference to an 'Adder' object. This, > >in turn, has a method called 'AddNumber'. > >Late Binding Example > >~~~~~~~~~~~~~~~~~ > >Dim o as Object > >Set o = new AxServer.Application > >For i = 1 to MaxCount > > o.Adder.AddNumber i > >Next > >Early Binding Example > >~~~~~~~~~~~~~~~~~ > >Dim o as AxServer.Application > Set o = new AxServer.Application ' This line missing in original > post... > >For i = 1 to MaxCount > > o.Adder.AddNumber i > >Next > >The Late binding example takes about 28 seconds and the early bound one > >takes about 42 seconds - I would have expected the opposite. NB if a WITH > >construct is used outside the loop, then the early binding example is > faster > >than the late one, as expected. > >Can anyone enlighten me to the reason for this? > >Neil McKechnie > >Microlink Associates Ltd
|
Sat, 10 Feb 2001 03:00:00 GMT |
|
|
|