-
Testing GoSub speed in VB6
So much has been said in 'Microsoft's C++ bigotry'' about the speed of GoSub
that I decided to give it a try.
I came up code below, which doesn't do anything, especifically to try the
speed of the different contructs.
The results are interesting.
Compiled in p-code:
GoSub - 1.85 seconds
Branching Sub - 9.57 Seconds
Compiled in native:
GoSub - 23.61 seconds (!)
Branching Sub - 0.62 seconds
This surprised me, even though I knew GoSub was slower in native, but THAT
much slower?
Before anyone starts an argument about my post, my ?0.02 on the subject are:
1) I don't use GoSub because find the resulting code hard to read/follow
2) Regardless of 1), GoSub should have made it into VB.NET
Miguel Santos
---Test Code - Feel Free to try and post your results---
Sub Main()
Dim t As Double, f As Long
'Test GoSub
t = Timer
For f = 1 To 10000000
DoSomeStuff1
Next
MsgBox Timer - t
'Test Branching Sub
t = Timer
For f = 1 To 10000000
DoSomeStuff2
Next
MsgBox Timer - t
End Sub
Private Sub DoSomeStuff1()
'GoSub
Dim a&, b&, c&, d&, e&, f&, g&, h&, i&, j&
GoSub DoSomeSmallStuff1
GoSub DoSomeSmallStuff1
GoSub DoSomeSmallStuff1
GoSub DoSomeSmallStuff1
GoSub DoSomeSmallStuff1
Exit Sub
DoSomeSmallStuff1:
Return
End Sub
Private Sub DoSomeStuff2()
'Sub calling other sub
Dim a&, b&, c&, d&, e&, f&, g&, h&, i&, j&
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
End Sub
Private Sub DoSomeSmallStuff2(a&, b&, c&, d&, e&, f&, g&, h&, i&, j&)
'Branching Sub
End Sub
-
Re: Testing GoSub speed in VB6
>The problem with your code as a benchmark was mainly that you were doing
>nothing at all in the routine -- the optimiser could cause whole calls to
>disappear. (In case you don't see it: in-lining small routines is a common
>optimisation -- if a routine does nothing, inlining it is easy!)
>
>To really measure the difference between a routine and GoSub, you're best
to
>compare both speeds against performing the same code in-line.
Right, but then the code you're executing takes part of the time
measurement.
Say that A is the GoSub Time, B is Sub Time, and C is the 'DoSomething'
code, then instead of comparing
A to B
we end up comparing
(A + C) to (B + C)
Which distorces the results.
I did compile my example with no optimizations in order to avoid in-lining,
I thought this would maintain the code structure, but I could be wrong.
Miguel Santos
-
Re: Testing GoSub speed in VB6
Miguel Santos wrote:
> So much has been said in 'Microsoft's C++ bigotry'' about the speed of GoSub
> that I decided to give it a try.
> I came up code below, which doesn't do anything, especifically to try the
> speed of the different contructs.
>
> The results are interesting.
> Compiled in p-code:
> GoSub - 1.85 seconds
> Branching Sub - 9.57 Seconds
>
> Compiled in native:
> GoSub - 23.61 seconds (!)
> Branching Sub - 0.62 seconds
>
> This surprised me, even though I knew GoSub was slower in native, but THAT
> much slower?
Irrespective of what I say below, this /is/ the order(s) of magnitude of the
performance problem I've seen reported before :-(
> Before anyone starts an argument about my post, my ?0.02 on the subject are:
>
> 1) I don't use GoSub because find the resulting code hard to read/follow
I've only used it in one situation in 8 years of VB programming, and,
ironically, it was to increase apparent speed when locating a large number of
loaded controls in VB3. However, I have also included working code from other
coders that used it...
> 2) Regardless of 1), GoSub should have made it into VB.NET
Me too, though I'd prefer not to have to put my arguments in brackets.
The problem with your code as a benchmark was mainly that you were doing
nothing at all in the routine -- the optimiser could cause whole calls to
disappear. (In case you don't see it: in-lining small routines is a common
optimisation -- if a routine does nothing, inlining it is easy!)
To really measure the difference between a routine and GoSub, you're best to
compare both speeds against performing the same code in-line. Here's my
version of your code and the results on my PIII 550MHz:
(All of these are from single runs with rather too much else running to really
provide more than an order of magnitude comparison. The first IDE run was with
Max a tenth of what it is now and the "DosomeStuff" functions returned
variants. I didn't record the base time for the IDE runs, but it would have
been about the same ratio as the compiled p-code i.e. about 35 seconds.)
Option Explicit
' GoSub Routine Base Disk Size
' IDE 8.82 38.86 (variants*10) (NTFS
' 8.47 36.14 (longs) Compressed)
' Opt 42.02 4.38 0.16 16K (4K)
' OptPro 42.29 4.21 0.19 16K (4K)
' Small 40.85 4.72 0.19 16K (4K)
' None 38.47 3.16 2.96 20K (6K)
' P-Code 4.84 28.25 25.36 12K (4K)
'
:
Sub Main()
Dim baseTime As Double
Dim t As Double
Dim f As Long
Dim r As Long
Const Max As Long = 10000000
Dim Msg As String
DoEvents
DoEvents
' Test in-line as a base time
t = Timer
For f = 1 To Max
r = DoSomeStuff0 - r
Next
baseTime = Timer - t
Msg = "Base time" & vbTab & baseTime & " seconds" & vbLf
DoEvents
DoEvents
'Test GoSub
t = Timer
For f = 1 To Max
r = DoSomeStuff1 - r
Next
Msg = Msg & "GoSub" & vbTab & (Timer - t - baseTime) & " seconds" & vbLf
DoEvents
DoEvents
'Test Branching Sub
t = Timer
For f = 1 To Max
r = DoSomeStuff2 - r
Next
MsgBox Msg & "Routine" & vbTab & (Timer - t - baseTime) & " seconds"
End Sub
'GoSub
Private Function DoSomeStuff1() As Long
Dim a&, b&, c&, d&, e&, f&, g&, h&, i&, j&
GoSub DoSomeSmallStuff1
b = a
GoSub DoSomeSmallStuff1
c = a
GoSub DoSomeSmallStuff1
d = a
GoSub DoSomeSmallStuff1
e = a
GoSub DoSomeSmallStuff1
DoSomeStuff1 = a
Exit Function
DoSomeSmallStuff1:
a = b + c + d + e + f + g + h + i + j + 1&
Return
End Function
'Sub calling other sub
Private Function DoSomeStuff2() As Long
Dim a&, b&, c&, d&, e&, f&, g&, h&, i&, j&
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
b = a
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
c = a
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
d = a
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
e = a
Call DoSomeSmallStuff2(a, b, c, d, e, f, g, h, i, j)
DoSomeStuff2 = a
End Function
'Branching Sub
Private Sub DoSomeSmallStuff2(a&, b&, c&, d&, e&, f&, g&, h&, i&, j&)
a = b + c + d + e + f + g + h + i + j + 1&
End Sub
Private Function DoSomeStuff0() As Long
Dim a&, b&, c&, d&, e&, f&, g&, h&, i&, j&
a = b + c + d + e + f + g + h + i + j + 1&
b = a
a = b + c + d + e + f + g + h + i + j + 1&
c = a
a = b + c + d + e + f + g + h + i + j + 1&
d = a
a = b + c + d + e + f + g + h + i + j + 1&
e = a
a = b + c + d + e + f + g + h + i + j + 1&
DoSomeStuff0 = a
End Function
-
Re: Testing GoSub speed in VB6
RemoveThisToMail_ms@netvisao.pt wrote:
> > The problem with your code as a benchmark was mainly that you were doing
> > nothing at all in the routine -- the optimiser could cause whole calls to
> > disappear. (In case you don't see it: in-lining small routines is a common
> > optimisation -- if a routine does nothing, inlining it is easy!)
> >
> > To really measure the difference between a routine and GoSub, you're best
> > to compare both speeds against performing the same code in-line.
>
> Right, but then the code you're executing takes part of the time
> measurement.
>
> Say that A is the GoSub Time, B is Sub Time, and C is the 'DoSomething'
> code, then instead of comparing
> A to B
> we end up comparing
> (A + C) to (B + C)
> Which distorces the results.
Yep. That is why I measure C, as best as possible, and subtract it -- look at
baseTime in my code.
> I did compile my example with no optimizations in order to avoid in-lining,
> I thought this would maintain the code structure, but I could be wrong.
OK.
If you look at my baseTime results for Native No optimisation ("None")
compared to any of the optimised versions, I'd guess the DoSomeStuff0 routine
has been in-lined, and then probably more optimised. So my attempt to measure
"C" is probably flawed. You can also get this impression from the relative
consistancy of the "A+C" and "B+C" times across all of the optimised versions.
I should add that I mis-typed Alt-I,S and sent that post prematurely.
The size stuff and Pentium Pro optimisation tests were just for completeness,
but clearly the program is too small/fast to see any significant differences.
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
-
Re: Testing GoSub speed in VB6
"Miguel Santos" <RemoveThisToMail_ms@netvisao.pt> wrote in message
news:3e37cfc3@tnews.web.devx.com...
> So much has been said in 'Microsoft's C++ bigotry'' about the speed of
GoSub
> that I decided to give it a try.
> I came up code below, which doesn't do anything, especifically to try the
> speed of the different contructs.
>
> The results are interesting.
> Compiled in p-code:
> GoSub - 1.85 seconds
> Branching Sub - 9.57 Seconds
>
> Compiled in native:
> GoSub - 23.61 seconds (!)
> Branching Sub - 0.62 seconds
>
> This surprised me, even though I knew GoSub was slower in native, but THAT
> much slower?
The test won't tell you anything useful about the potential performance
gains from using Go. Microsoft put a wait loop into it in VB4.
If you were to load up an old copy of VB3 and try again, you might see
something radically different.
--
Regards
Jonathan West
-
Re: Testing GoSub speed in VB6
> Microsoft put a wait loop into it in VB4.
Jonathan: Are you serious, or is that hyperbole? I don't believe that MS
intentionally slowed down GoSub in VB4. My impression is that they
re-implemented GoSub with the rewrite in C++/COM, and simply never got
around to optimizing it.
--
Phil Weber
-
Re: Testing GoSub speed in VB6
"Phil Weber" <pweber@nospam.fawcette.com> wrote in message
news:3e385425$1@tnews.web.devx.com...
> > Microsoft put a wait loop into it in VB4.
>
> Jonathan: Are you serious, or is that hyperbole? I don't believe that MS
> intentionally slowed down GoSub in VB4. My impression is that they
> re-implemented GoSub with the rewrite in C++/COM, and simply never got
> around to optimizing it.
I was being facetious - certainly the performance did take a nosedive in
VB4, and MS did write a KB article about it, saying the performance was bad,
and they never did attempt to fix it.
--
Regards
Jonathan West
-
Re: Testing GoSub speed in VB6
"Jonathan West" <jwest@mvps.org> wrote in message
news:3e384e29$1@tnews.web.devx.com...
>
>
> The test won't tell you anything useful about the potential performance
> gains from using Go.
Potential? Come on...
VB4 -> GoSub slow
VB5 -> GoSub slow
VB6 -> GoSub slow
VB.NET -> GoSub gone
Somehow I fail to see the potential here 
Regards,
Miguel Santos
-
Re: Testing GoSub speed in VB6
On Wed, 29 Jan 2003 23:19:25 -0000, "Miguel Santos"
<RemoveThisToMail_ms@netvisao.pt> wrote:
>
>"Jonathan West" <jwest@mvps.org> wrote in message
>news:3e384e29$1@tnews.web.devx.com...
>>
>>
>> The test won't tell you anything useful about the potential performance
>> gains from using Go.
>
>Potential? Come on...
>VB4 -> GoSub slow
>VB5 -> GoSub slow
>VB6 -> GoSub slow
>VB.NET -> GoSub gone
>
>Somehow I fail to see the potential here 
It's a high potential, but a low probability.
GoSub can be (and could have been in previous versions) implemented
using code substitution. In that case there would be zero overhead.
That was more difficult when they had to support both an interpreter
and a compiler, but with VB.Net that should no longer be an issue.
If they don't care, it doesn't matter though.
Dan
Language Stability is a *feature* I wish VB had!
(#6)/(#1!)
Error 51
Error 3
Error 9
....
-
Re: Testing GoSub speed in VB6
Dan Barclay wrote:
> On Wed, 29 Jan 2003 23:19:25 -0000, "Miguel Santos"
> <RemoveThisToMail_ms@netvisao.pt> wrote:
> > "Jonathan West" <jwest@mvps.org> wrote in message
> > news:3e384e29$1@tnews.web.devx.com...
> > >
> > > The test won't tell you anything useful about the potential performance
> > > gains from using Go.
> >
> > Potential? Come on...
> > VB4 -> GoSub slow
> > VB5 -> GoSub slow
> > VB6 -> GoSub slow
> > VB.NET -> GoSub gone
> >
> > Somehow I fail to see the potential here 
>
> It's a high potential, but a low probability.
:-)
> GoSub can be (and could have been in previous versions) implemented
> using code substitution. In that case there would be zero overhead.
That would require structured use, so I'd prefer a structured syntax to force
it.
(I actually didn't like Next being structured when I first used VB -- after
not using Basic since Commodore 64.
There are situations where you would now use Exit For and flags or other
convoluted code where allowing Next to happen makes things clear:
For I = 1 To Length
If Something(i) Then
DoThis
Next
DoThat
Exit Sub
End If
Next
NotFound
There's lots of reasons why this is bad, but there's a galah at the window
wanting some seed.)
> That was more difficult when they had to support both an interpreter
> and a compiler, but with VB.Net that should no longer be an issue.
Actually, this emphasises that a useful compromise would be Pascal-like
sub-subroutines where all local variables are available to the internal
routine. When compiled, in-lining optimisation would give you the code
substitution without loosing source code structure.
Now for a syntax:
Sub OuterRoutine(Arg As String)
' Need to Dim variables before sub-sub for readability
Dim LocalVar As String
' In keeping with a number of VB.NET syntax designs let's define a new
keyword unneededly here:
InnerSub InnerRoutine(InnerArg As String)
' Can access Arg, LocalVar and InnerArg here.
' NB alias issues if InnerArg is ByRef, but there is always this issue with
ByRef.
End InnerSub
' Code for OuterRoutine continues
LocalVar = 134
InnerRoutine(LocalVar + Arg)
' Now to highlight issues...
' Does this make sense?
With SomeObject
InnerSub InnerR2(IArg2 As String)
.Property = IArg2
End InnerSub
' Calling InnerR2 makes sense here:
InnerR2(Trim(.Property))
End With
' But it wouldn't make sense to call InnerR2 here, but
' it was declared in a different scope, so it
' shouldn't be available anyway.
InnerR2("") ' Compile Error expected
' A sub-sub in a Try is about the same as With, except for Exit Try:
' A sub-sub in a loop (or Try) with and Exit loop (or Try) statement inside
it doesn't make sense.
End Sub
Anyway, this looks like a useful way to provide GoSub and macro replacements
where top-level routines are overkill.
Note also that this extension was a possibility for C as well, but I don't
remember any specific issues with it there (other than comments like "If you
want Pascal, use Pascal.").
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
-
Re: Testing GoSub speed in VB6
Mark Hurd wrote:
> There's lots of reasons why this is bad, but there's a galah at the window
> wanting some seed.)
Yes, I work from home, in a semi-rural Adelaide suburb, but I didn't intend
sending this as is ;-)
The drought means we have galahs ripping up lawn roots and some have been tame
enough to ask for more...
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
-
Re: Testing GoSub speed in VB6
On Fri, 31 Jan 2003 12:14:00 +1030, Mark Hurd wrote:
> Mark Hurd wrote:
>> There's lots of reasons why this is bad, but there's a galah at the window
>> wanting some seed.)
>
> Yes, I work from home, in a semi-rural Adelaide suburb, but I didn't intend
> sending this as is ;-)
>
> The drought means we have galahs ripping up lawn roots and some have been tame
> enough to ask for more...
>
> Regards,
> Mark Hurd, B.Sc.(Ma.) (Hons.)
Will anyone outside of Australia know what a Galah is? 
Cheers,
Jason
(working from home when not lecturing in Melbourne )
-
Re: Testing GoSub speed in VB6
Jason Sobell iGadget wrote:
> On Fri, 31 Jan 2003 12:14:00 +1030, Mark Hurd wrote:
> > Mark Hurd wrote:
> > > There's lots of reasons why this is bad, but there's a galah at the
> > > window wanting some seed.)
> >
> > Yes, I work from home, in a semi-rural Adelaide suburb, but I didn't
> > intend sending this as is ;-)
> >
> > The drought means we have galahs ripping up lawn roots and some have been
> > tame enough to ask for more...
>
> Will anyone outside of Australia know what a Galah is? 
There should be some witty comment about MM here, but it wouldn't be
understood either...
Regards,
Mark Hurd, B.Sc.(Ma.) (Hons.)
-
Re: Testing GoSub speed in VB6
On Fri, 31 Jan 2003 12:02:46 +1030, "Mark Hurd"
<markhurd@ozemail.com.au> wrote:
>> It's a high potential, but a low probability.
>
>:-)
>
>> GoSub can be (and could have been in previous versions) implemented
>> using code substitution. In that case there would be zero overhead.
>
>That would require structured use, so I'd prefer a structured syntax to force
>it.
Proper implementation is transparent. It would not *require* any
different usage than it currently does.
OTOH, if you prefer structured syntax, you can use Delphi<g>. Or they
could add the structured form (nested procs) and deprecate GoSub for
*later* removal.
The issue is language stability, not just how to solve this
structure/feature issue.
Dan
Language Stability is a *feature* I wish VB had!
(#6)/(#1!)
Error 51
Error 3
Error 9
....
-
Re: Testing GoSub speed in VB6
On Fri, 31 Jan 2003 18:18:19 +1100, Jason Sobell iGadget
<igadget_@hotmail.com> wrote:
>Will anyone outside of Australia know what a Galah is? 
Another kind of sheila, but even more willing...?
MM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|