From: Mike Williams on
"Tom Shelton" <tom_shelton(a)comcastXXXXXXX.net> wrote in message
news:eeWP5NuQKHA.1876(a)TK2MSFTNGP06.phx.gbl...

> But, again, the preformance difference is in factions of a second.
> Not even worth talking about outside of news groups.

In percentage terms it is a lot, with the VB6 .bmp colour counting code
running about five times faster than the VB.Net code, regardless of the fact
that it is just fractions of a second for a single relatively small image.

> It would be trivial really to just read the bitmap data directly
> from the bitmap file . . .

Yes, in fact that's what I was going to do, and it would have resulted in a
small speed increase, except that I intended to eventually add the code to
handle jpegs and other bitmap images etc and so I decided to load the bmp
into a DIBSection (which in any case is almost the same thing) so that the
code would still work when I eventually added code to load and decode a jpg
into a DIB.

> . . . rather then use the bitmap class, etc - but the bitmap class
> can handle bmp, gif, png, etc, etc. Like with most things - if
> speed is unacceptable, then I find the bottle neck and then
> see if there is a faster way to accomplish it.

The bottleneck is in your For Next loop code, not in the part that appears
to be loading the image using the bitmap class or whatever. Try moving the
start timer to immediately before the start of the For Next loop to see what
I mean. The bottleneck definitely appears to be inside the For Next loop,
probably the stuff dealing with the Dictionary.

> I agree that people shouldn't be making all kinds of speed
> claims - but, it goes both ways.

Yes, it does. That's why I've always said that if the likes of McCarthy and
Clark and Ligthert stop deliberately causing trouble in the VB6 group then I
(and presumably others) will immediately stop retaliating :-)

Mike



From: Tom Shelton on
On 2009-10-01, Mike Williams <Mike(a)WhiskyAndCoke.com> wrote:
> "Tom Shelton" <tom_shelton(a)comcastXXXXXXX.net> wrote in message
> news:eeWP5NuQKHA.1876(a)TK2MSFTNGP06.phx.gbl...
>
>> But, again, the preformance difference is in factions of a second.
>> Not even worth talking about outside of news groups.
>
> In percentage terms it is a lot, with the VB6 .bmp colour counting code
> running about five times faster than the VB.Net code, regardless of the fact
> that it is just fractions of a second for a single relatively small image.
>
>> It would be trivial really to just read the bitmap data directly
>> from the bitmap file . . .
>
> Yes, in fact that's what I was going to do, and it would have resulted in a
> small speed increase, except that I intended to eventually add the code to
> handle jpegs and other bitmap images etc and so I decided to load the bmp
> into a DIBSection (which in any case is almost the same thing) so that the
> code would still work when I eventually added code to load and decode a jpg
> into a DIB.
>
>> . . . rather then use the bitmap class, etc - but the bitmap class
>> can handle bmp, gif, png, etc, etc. Like with most things - if
>> speed is unacceptable, then I find the bottle neck and then
>> see if there is a faster way to accomplish it.
>
> The bottleneck is in your For Next loop code, not in the part that appears
> to be loading the image using the bitmap class or whatever. Try moving the
> start timer to immediately before the start of the For Next loop to see what
> I mean. The bottleneck definitely appears to be inside the For Next loop,
> probably the stuff dealing with the Dictionary.
>

Ah, that very well could be. I'll play with that bit. One problem is
probably the use of bitconverter as well. changing that line alone to

Dim color As Integer = RGB(bytes(i), bytes(i + 1), bytes(i + 1))

lowers the execution time to:

Counted 131763 unique colors in 00:00:00.0940000
Counted 131763 unique colors in 00:00:00.0780000
Counted 131763 unique colors in 00:00:00.0620000
Counted 131763 unique colors in 00:00:00.0630000
Counted 131763 unique colors in 00:00:00.0780000
Counted 131763 unique colors in 00:00:00.0620000
Counted 131763 unique colors in 00:00:00.0630000
Counted 131763 unique colors in 00:00:00.0620000
Counted 131763 unique colors in 00:00:00.0630000
Counted 131763 unique colors in 00:00:00.0620000
Average Time: 00:00:00.0690000
Press any key to continue . . .

So, this maybe an optimization issue. The dictionary is very fast at
retrieving, but is slower adding because it is a hash table. let me try a
couple of more changes - then maybe this might be better.

>> I agree that people shouldn't be making all kinds of speed
>> claims - but, it goes both ways.
>
> Yes, it does. That's why I've always said that if the likes of McCarthy and
> Clark and Ligthert stop deliberately causing trouble in the VB6 group then I
> (and presumably others) will immediately stop retaliating :-)

Mike - you and yours cause as much trouble as we .net'rs do. You invite the
problems by the way you malign .net when people accidently post. Can't you
just redirect and let it go? You and mayayanna are the worst that way.

--
Tom Shelton
From: Mike Williams on
"Tom Shelton" <tom_shelton(a)comcastXXXXXXX.net> wrote in message
news:ONBxECvQKHA.4244(a)TK2MSFTNGP06.phx.gbl...

>> [Mike said] The bottleneck is in your For Next loop code, not in the
>> part that appears to be loading the image using the bitmap class or
>> whatever. The bottleneck definitely appears to be inside the For Next
>> loop, probably the stuff dealing with the Dictionary.
>
> [Tom said] Ah, that very well could be. I'll play with that bit. One
> problem is probably the use of bitconverter as well. changing that
> line alone [code snipped] to lowers the execution time to:
> Counted 131763 unique colors in 00:00:00.0620000 [average]

Yep, that seems to have brought it down somewhat, but of course the main
bottleneck still appears to be the dictionary.

> So, this maybe an optimization issue. The dictionary is very fast
> at retrieving, but is slower adding because it is a hash table. let
> me try a couple of more changes - then maybe this might be better.

Okay. But don't worry about it too much. I think we've already posted too
many messages in this thread already :-). Personally I think you'll need to
get rid of the dictionary altogether if you want to coax a lot more speed
out of it. I know in my case getting the original major bottleneck out of
the way was relatively easy, requiring only fairly small changes in code,
but trimming off the smaller bottlenecks to "see if we can just squeeze a
few more milliseconds out of this thing" was a lot harder. For example, my
original code had just eight lines of code inside the For Next loop (where p
is a VB Long and TwoToThePowerOf is small "look up" array containing eight
Bytes):

For j = 1 To SourceWidth * SourceHeight * 3 Step 3
p = &H10000 * SourceArray(j) + &H100& * SourceArray(j + 1) + SourceArray(j
+ 2)
allclrsByte = p \ 8
bitmask = TwoToThePowerOf(7 - p Mod 8)
z = clrs(allclrsByte)
If (z And bitmask) = 0 Then
used = used + 1
clrs(allclrsByte) = z Or bitmask
End If
Next j

In fact my original testbed code was even much smaller than the above,
because most of the 8 code lines in the above loop are concerned with using
individual bits (rather than whole bytes or whatever) to record each colour
actually used. Anyway, the above loop produced an overall code time of about
0.021, with about 0.005 of that taken up by LoadImage and the remaining
0.016 taken by the loop.

Then I began to think that I could squeeze a few more milliseconds out of
that by getting rid of the three individual Byte array reads and the math in
the line in the first code line within the loop. In order to do that I
decided to address the data using VB6 Longs instead of Bytes, with one Long
reading three bytes of data and masking out the unwanted byte. Seems
reasonable except for the fact that using a VB6 array of Longs allows you to
step one long (or more than one Long) at a time through the array, whereas I
wanted to step just 3 bytes (VB6 doesn't have any of this fancy stepping a
Long through a Byte array any number of bytes at a time that judging by your
own code you appear to have in .Net), and a copymemory in the loop was out
of the question because it would be too slow. So, in order to perform the
trick I wanted to perform and to do it in a fast way I needed to persuade
VB6 to step a Long through an array of byte data three bytes at a time,
which VB6 cannot do and which required me to mess about using all the
SafeArray stuff to point four separate VB6 Long arrays all at slightly
different points in the same single block of data bytes. That caused the
code in the loop to grow from just 8 lines to a whopping 68 lines! In
addition to that there were all the additional declarations and things that
were required outside the loop, adding even more lines of code.

Anyway, the result was some extremely long (and I must admit quite rambling
at the moment!) code, with the 68 line loop actually executing about 0.006
seconds faster than the previous 8 line loop, resulting in the loop time
changing from 0.016 to 0.010 seconds and changing the overall time from
0.021 seconds to about 0.015 seconds. This behaviour of ever diminishing
returns for ever more additional code probably applies to most programming
languages when attempting to squeeze out those extra few milliseconds, and
in my case it produced an extremely rambling mess of spaghetti (because I
was concentrating on testing the theory rather than writing neat code), but
it does work very fast.

I'm sure that you will be able to squeeze similar performance out of your
VB.Net code once you start tweaking it (although I'm fairly sure you will
need to get rid of the dictionary in order to do so) but as far as I am
concerned, even if you do, I will have managed to prove my point in my
argument with Cor Ligthert.

> Mike - you and yours cause as much trouble as we .net'rs do.
> You invite the problems by the way you malign .net when
> people accidently post.

Yes, some of us sometimes do that, but the catalyst for that behaviour was
the appearance on the VB6 group of certain dotnetters who were specifically
out to cause trouble, many of whom derided VB6 programmers in the group and
called them last century dummies who were stuck with VB6 because they were
incapable of learning anything else, which is most definitely not true.

> just redirect and let it go?

Yes. I'll start doing that immediately. In fact I'll stop posting any of the
messages to which you refer, but I'll only do it if the dotnetters who are
currently deliberately attempting to cause trouble in the VB6 group also
immediately stop doing it. Seems fair to me.

Anyway, I think this thread can be considered closed now. It's long enough
already. I'd still like to know how that compiled exe I sent you runs at
your end though, and how much speed to manage to squeeze out of your net
code when the dictionary is removed. It's been fun, but I think it's time to
go now ;-)

Mike



From: Mike Williams on
"Tom Shelton" <tom_shelton(a)comcastXXXXXXX.net> wrote in message
news:euEnpegQKHA.4692(a)TK2MSFTNGP06.phx.gbl...

> That is not the results I'm getting at all... I'm not sure what your
> doing
> here. but on my machine - maximized at 1680x1050 with the drawing code
> removed from the rowcomplete in the vb.net code...
>
> VB6:
> MT: 5.30 sec
> ST: 6.55 sec
>
> VB.NET:
> MT: 1.203 sec
> ST: 2.344 sec

Just for the record, as has since been established, the figures you quote
above were achieved when you inadvertently left the picSrf.Refresh in Olaf
Schmidt's code, so that you were running it while it was still peforming
graphic operations whereas you were running your own VB.Net code when it was
not doing so. After commenting out the picSrf.Refresh in Olaf's code you
discovered that the figures were very different. In fact, under those
conditions on my own 2.4 Ghz Intel machine with the Form maximized on a 1680
x 1050 display (similar setup to your own) Olaf's code gives me:

VB6:
MT: 1.32 sec
ST: 2.66 sec

Mike





From: Mike Williams on
"Schmidt" <sss(a)online.de> wrote in message
news:e4zZaR$QKHA.1372(a)TK2MSFTNGP02.phx.gbl...

> [Addressed to Tom Shelton] Looks not right (yet) to
> me (your MT-result). With entirely disabled GDI-
> refreshs, the timing should scale nearly lineary with two
> threads (on a DualCore).Y our 2.77 seconds for the
> singlethreaded run look more plausible anyways...
> But on my machine the two-threaded timing scales
> down to nearly exactly the half of the singlethreaded
> timing - would mean - you should get about:
> ST: 2.77 / 2 = MT: 1.39 seconds on your 2.4 GHz-Dualcore.

Your calculations seems to be spot on there, Olaf. I'm using a 2.4 Ghz
processor (the same 2.4 GHz Intel 6600 that I believe Tom Shelton uses,
except mine is a quad core whereas his is a dual core) and when running
maximized at the same 1680 x 1050 resolution that I believe Tom uses your
VB6 code gives me:

VB6:
MT: 1.32 sec
ST: 2.66 sec

The only reason I can think of why Tom Shelton's dual core is not scaling
linearly between running single or multi thread is perhaps when running your
code he has some background task running which is using a fair amount of
processor time?

Mike