From: Donald Lessau on 17 Mar 2010 11:25
"Mike Williams" <Mike(a)WhiskyAndCoke.com> schrieb im Newsbeitrag
> "Schmidt" <sss(a)online.de> wrote in message
>> Speaking of Calling-Overhead, maybe something
>> that worth' mentioning too. Even in calling VBs
>> "plain, ownerdefined Functions" are larger differences,
>> depending on *where* you place them (Form-,
>> Class- or *.bas-Modules) and how you attribute them
>> (Private, Friend, Public).
>> One can measure that easily (Mike?... ;-)) by placing
>> just a simple "Long-Reflection-Function" in different
>> Modules (changing some Attributes where they apply).
>> In short, something like that:
>> Public Function ReflectLong(Byval LngParam) As Long
>> ReflectLong = LngParam
>> End Function
> There's that Variant again, Olaf ;-)
> Actually I would imagine that's just a "typo" and that you have probably
> used a Long in your real test code. I get the following at this end (when
> using Byval LngParam as Long), for the three specific tests I've conducted
> on my Celeron laptop:
> 05 nanoseconds (Public in Module)
> 08 nanoseconds (Private in Form)
> 51 nanoseconds (Public in Form)
Try Friend in Form, should be clearly faster than Public in Form.
From: Mike Williams on 17 Mar 2010 13:15
"Donald Lessau" <don(a)oflex.com> wrote in message
> Try Friend in Form, should be clearly faster
> than Public in Form.
Yep, it is. Give or take a gnat's whisker I get:
52.4 weeks (Public in Form) - OK, nanoseconds, not weeks ;-)
6.4 nanoseconds (Private in Form or Friend in Form)
4.4 nanoseconds (Public in Module)
From: Karl E. Peterson on 17 Mar 2010 15:28
Tony Toews [MVP] wrote:
> MM <kylix_is(a)yahoo.co.uk> wrote:
>>> So close! And yet, so far.
>> Did you find the fastest routine, Mike?
>> Well, sure I did, Karl!
>> How'dya do that, then, Mike?
>> Well, gosh durn it, Karl, ya know what? I just stuck in different
>> routines to call until I found one that was fastest!
> I was thinking that this entire thread summarized would be an
> excellent column for Karl to write. It would never have occurred to
> me that a Typelib would be that much faster then a DLL declaration.
The thing is, VB never calls just the API you ask it to. At the very
least, it also calls GetLastError. At the *very* least. (I stress
that because I'm fairly sure it's also calling its own routines in the
runtime to set the value for Err.LastDllError, and a few other things.)
If Strings are involved, it plays all sorts of tricks.
One of the few typelibs I use somewhat routinely, though, is one that
simply has CopyMemory declared *without* the extra call to
GetLastError. That can make a measurable, if not noticable, difference
when you're working with *lots* of data in memory-mapped files.
But in general, going to that level of optimization is
counter-productive. As Jim (correctly) pointed out here, the endian
swaps are far more efficient in native code than by any other method.
They must be. I went so far as running tests with all the
GetMem*/PutMem* calls from the runtime, declared in a typelib, as a
test of that theory many years ago.
..NET: It's About Trust!
From: Bob O`Bob on 17 Mar 2010 15:49
> On Tue, 16 Mar 2010 20:38:03 -0600, "Tony Toews [MVP]"
> <ttoews(a)telusplanet.net> wrote:
>> "Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote:
>>> 0.056 microseconds for Nobody's VB method
>> I sure wish nobody would change their name to somebody. <smile>
> Yeah, but somebody would be just as anonymous. A new moniker entirely,
> perhaps? How about "Monica", Nobody? Somebody? Anybody?
If it's up for a community vote, I suggest "Bueller"
From: Mike Williams on 17 Mar 2010 17:59
"Karl E. Peterson" <karl(a)exmvps.org> wrote in message
> As Jim (correctly) pointed out here, the endian
> swaps are far more efficient in native code than
> by any other method. They must be.
Well there is no "must" about it Karl, and personally I don't go with that
at all. In fact the speed tests I've carried out on both my laptop and on my
desktop machines show it not to be the case. I would agree that if you are
calling a declared function which ends up executing a block of machine code
which is essentially the same as the machine code that the VB compiler comes
up with then the VB compiled code would be faster because it does not have
the call overhead of the function. However, in many cases, and in this
specific case, the VB compiled code is /not/ the same as the code in the
called function, regardless of the fact that it is essentially performing
the same task. Here is the fastest of the VB6 routines we were looking at:
SwapEndian08 = _
(((dw And &HFF000000) \ &H1000000) And &HFF&) Or _
((dw And &HFF0000) \ &H100&) Or _
((dw And &HFF00&) * &H100&) Or _
((dw And &H7F&) * &H1000000)
If (dw And &H80&) Then SwapEndian08 = SwapEndian08 Or &H80000000
It consists of lots of ANDs and ORs and integer divides and multiplies and
although it is more than twenty years since I coded in machine code or ASM
(and a lot has changed in that time!) I am absolutely totally 100 percent
convinced that regardless of how the VB compiler optimises that VB code it
will not come up with anything even remotely as fast as the machine code
that is being called in Jim Mack's DLL, which according to Jim Mack is:
mov eax, [esp+4]
That is a very efficient swap and even though in both cases it is only a
small task that is being carried out (just a single swap) the hand crafted
machine code will still have a significant advantage (the machine code
routine itself) over the code generated by the VB compiler. In cases where
it is possible to hand craft machine code that performs a specific task in a
more efficient manner than any machine code the VB compiler can be persuaded
to come up with (as is definitely the case here and as willbe the case in
many other circumstances) then it is entirely possible for the hand crafted
machine code to perform its task faster than compiled VB code, even after
accounting for any overheads. It all depends on how much of a speed
advantage the hand crafted machine code has over the VB compiled machine
code (if any) and on how much of that advantage is wiped out by the overhead
of a call to a standard declared DLL function (if you are using a DLL
instead of exposing it as a TypeLib).
In this specific case your own assessment is correct /only/ when the hand
crafted code is being called in a standard declared DLL function, where in
this case the overhead of the call to a standard declared DLL function
entirely wipes out the speed advantage of the hand crafted code, and only
then because they are both performing only a single swap and the overall
total speed advantage in nanoseconds is fairly minimal. In this specific
case it wipes out the advantage sufficiently to actually negate it,
resulting in the VB compiled code being overall about 30 per cent faster,
but in the case of the hand crafted code being exposed as a TypeLib it
retains most if not all of its machine code speed advantage, resulting in
the code exposed as a TypeLib being about three times as fast overall as the
compiled VB code. As with most things, it's horses for courses. I would
agree that optimization to this level is not always either necessary or
desireable, but in some cases it definitely would be, depending on the
specific task you are performing and on how important speed is to you.
I have just repeated the same tests I carried out the other day, both on my
laptop and on my desktop machine, and here are the results on my desktop
machine (the laptop results show pretty much the same pattern, although they
are all a bit slower). The timings are per iteration of the test loop,
averaged over a number of runs in all cases.
12.3 nanoseconds - Jim Mack's DLL as a Public function in module
9.4 nanoseconds - Compiled VB code using all optimizations
3.1 nanoseconds - Jim Mack's DLL exposed as a TypeLib
The results speak for themselves.