Link to home
Start Free TrialLog in
Avatar of Shane Russell
Shane RussellFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Performance improvements for this Q ( follow up question )

Hi all,

I just wanted to know if there were any improvements that could be made to the coding from my previous question :

https://www.experts-exchange.com/questions/21348688/how-to-decode-this-in-visual-basic.html#13535268

If so what are they and can I please have examples :)

Thank you all !!
SOLUTION
Avatar of aikimark
aikimark
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This will be pretty fast.  I'm sure it can be optimized further:

Private Function BinToStr(bin As String) As String
   
    Dim i As Long, Count As Long
    Dim strCompare(1) As String
    Dim b() As Byte
    ReDim b(0 To Len(bin) / 8 - 1)
   
    Debug.Assert Len(bin) Mod 8 = 0
   
    Dim strNibble As String
    strNibble = "0000-0001-0010-0011-0100-0101-0110-0111-" & _
                        "1000-1001-1010-1011-1100-1101-1110-1111-"
                       
    For i = 1 To Len(bin) - 7 Step 8
        strCompare(0) = Mid$(bin, i, 4)
        strCompare(1) = Mid$(bin, i + 4, 4)
        b(Count) = (InStr(1, strNibble, strCompare(0) & "-") - 1) / 5 * 16 + (InStr(1, strNibble, strCompare(1) & "-") - 1) / 5
        Count = Count + 1
    Next i
       
    BinToStr = StrConv(b, vbUnicode)
                       
End Function
Paul,

* Very good start.
* two Nibbles/pass => byte/pass => character/pass
* single operation to convert byte array back into string
* clever use of the Instr() function as a table lookup
Avatar of Shane Russell

ASKER

You said "Before I show code examples I need to know if the string length is guaranteed to be a multiple of 8 or if the leading zero characters ("0") might have been removed."

Would you be able to do an example of each ie that they are multiple of 8, and have zero characters ("0") and then the same but without the zero characters ("0") and then the same again but with another multiple ie 7 , basically something that is valid with regards to binary.

Just curious how it is done with and without ("0")'s and also using a different multiple :)

Thanks all !
gecko_au2003,

The only difference is a check of the length and prepending (concatenation) of a string of "0" characters to make the string length a multiple of 8.  All the processing code needs to have enough characters to construct 8-bit bytes.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I loved Idle_Minds method of using a lookup table for the conversion !! However PaulHews example of removing padding was great ! Thank you all !!
IdleMind, that may work faster, but I feel that takes much memory. So I feel it is not a good idea to use collection.
mgh_mgharish,

Unfortunately, your solution is very similar to those in the original question
and suffers from
* bit-at-a-time processing
* character-at-a-time concatenation
* operation reduncancy (recalculation of same values)
* large character string operations

<<...but the code in the previous one is the best one>>
This question was my idea.
I'm looking for performance improvement suggestions.

=================================
gecko_au2003,

Let's stick with 8 bit characters and realize that things can be done in other
groupings of binary digits...Which reminds me of an appropriate geeky riddle:


Q: Why is Halloween like Christmas?

A: Because Oct 31 = Dec 25
Yes.. of course..

>Unfortunately, your solution is very similar to those in the original question.
It is the original solution itself with For Loop removed.

When you are making a converter, I feel memory is one which should be taken care of, along with time, which is the most important one. Idle_Mind's solution will give the fastest running code, but lags in memory usage.
Idle_Mind's is faster than mine by about 30%  Times in seconds for 10K iterations.

Mine 2.261719
IdleMind's 1.722656

> IdleMind, that may work faster, but I feel that takes much memory. So I feel it is not a good idea to use collection.

mgh_mgharish how much memory does it take up?  Not counting collection and string overhead,
256 strings * 16 bytes (8 chars unicode) for the key and 256 * 16 bytes (integer) for the values = 8K
By my reckoning, not a lot on systems with hundreds of megabytes of memory...
Of course it depends on the application.
It adds a little bit of work for a one time load (which doesn't have to be done on form_load, one could test if the
collection is nothing and then initialize it.)

Personally I think it's a great optimization.

Memory is often sacrificed for performance.  That's the whole idea of using a lookup table...
Idle_Mind,

Very good.
* precalculate 256 table values for lookup
* use built-in hashing of collection for conversion
* byte-at-a-time processing
* single operation to convert back to string
* space/time tradeoff for performance

I'm not sure how much overhead a collection consumes in additional
memory per added item.  Also, I don't know if we might improve on
the collection hashing algorithm with a version of our own. (mod 256)
In order to compare, we'd need to run these top two contenders
through some iterations with different length strings.  You are correct
to state that the initial overhead of creating the collection lookup table
diminishes the more conversion is done, either longer strings or repeated
conversions of different strings.
Paul & Idle,

I must say that your responses were what I was expecting... clever and fast.

In fact, this has been a very rapid discussion thread.  I'm sad it ended so quickly.
We contributed much in just under 2 hours.  I didn't even submit any code because
your contributions were QUITE good enough.  Thank you.

and, lastly, thanks to gecko for posting the question and offering the points.
Definite kudos to PaulHews for the use of StrConv() to convert the byte array to a string.
That alone is a huge improvement over concatenating strings using the typical x = x & y approach.

Need to remember to use StrConv() more often...

I agree...thanx gecko for posting an interesting question.

It gets boring answering variations of the same basic questions over and over and over...   =)
mgh_mgharish,

I suppose that in certain embedded systems with very little memory a lookup table might not the best choice.

Of course, in most embedded systems with few resources we don't use BASIC do we?

It all depends on your target system and requirements...
Yes.. Thanks
(for posterity) Here's what I was thinking...

* build (0 to 1, 0 to 4369) lookup byte array.  
  This array is mostly sparse except for 16 positions corresponding
  to the possible nibble configurations (in hex).  The 16 significant
  positions will be equal to the low order and high order nibble values.
  &h00, &h10, &h20, &h30, &h40, &h50, &h60, &h70, etc.
  &h00, &h01, &h02, &h03, &h04, &h05, &h06, &h07, etc.
* use strconv() to convert the entire unicode string into a byte array
* use memory copy Windows API function to copy 8 bytes
  into a structure of two long integer variables
* xor the two long integer values with 1212696648 (&h48484848).
  This converts the two possible ASCII values, chr(48)="0" and chr(49)="1",
  into four 00 or 01 bytes.
* use the values in the two long integers to index into the
  lookup byte array.  No hashing required.
* the two lookup nibble values are ORed to create the byte value for the character.
* the strconv() function is used to create a unicode string

I use the most memory (8738 bytes) for my lookup table.  But my lookup table
can be generated in 16 iterations.

======================================
Note: I'm padding strings with "0" characters to make them a multiple of 8 characters,
rather than trimming to a length of 8.  I'm not sure I was clear on that earlier.
Paul & Idle & gecko,

What do you think?  I opined about your code.  Now it's your turn :-)

It is possible to only use one dimension of the lookup table and shift
the bits of the high order nibble by * 16.  It would cut my lookup table
memory requirement in half and only add one integer operation.
oops!

I should have done my coding before I posted my comment. :-(

My lookup table would need to be 16MB big :-o

I could still do the character construction with the lookup table
I originally proposed and index with
the nibbles converted to numeric values through a VB trick:
"&h" & Mid(inputstring,i,4) and "&h" & Mid(inputstring,i+4,4)
produce an acceptable range of nibble index values.
I was just reading it.  I like the xor to return the 0/1 bytes.  Using that technique, a calculated
method (with a tiny lookup table for powers of two) performs almost as well as Idle_Mind's proposal.  With
the lookup table you describe, it should rip even faster than Idle_Mind's.  When you post the code, I'll test them side by side.

Including code for a new calculated method that uses your xor idea.

Private Function BinToStr3(bin As String) As String
    'new calculated method
    Dim i As Long, j As Long, Count As Long
    Dim strCompare As String
    Dim bytIn() As Byte
    Dim b() As Byte
    Dim bytOut() As Byte
    Static Power(7) As Byte
   
    'One time initialization
    If Power(7) <> 128 Then
        For i = 0 To 7
            Power(i) = 2 ^ i
        Next
    End If
   
    If Len(bin) Mod 8 <> 0 Then
        bin = Right$(bin, 8 * (Len(bin) \ 8))
    End If
   
    bytIn = StrConv(bin, vbFromUnicode)
    ReDim b(UBound(bytIn))
    ReDim bytOut(0 To Len(bin) / 8 - 1)
   
   
   For i = 0 To Len(bin) - 8 Step 8
        For j = 0 To 7
            If bytIn(i + j) Xor 48 Then
                bytOut(Count) = bytOut(Count) + Power(7 - j)
            End If
        Next j
        Count = Count + 1
   Next i
   
    BinToStr3 = StrConv(bytOut, vbUnicode)
   
End Function

Results:
My Original 2.273438
Xor 1.792969
Idle_Mind's 1.710938


I have never seen anything or done anything with regards to binary or decoding it or anything like that programitically. Personally I am learning a lot myself and the only reason I asked the 2 questions I did with binary was because of the question I came across that was asked to decode the binary which gave that message with regards to the lousy t shirt or w/e that message gave lol.
With regards to asking a question that was different and not variants of simmilliar questions, your welcome. I love learning new things and I guess I am attention defacet to some degree with regards to I dont like going over the same things more then a certain amount of times, especially once I understand how it is done. I think all this binary stuff will take quite some time for me to absorb and understand.
I wont be going through it straight away because of some personal things I am sorting out at this point in time :)

I have done a little bit of c++, java, java script, vbscript amongst other things and still have a lot to learn. Eventually I plan on getting books with regards to a lot of programming languages and learning them, not sure If I already mentioned this or not but that is my intentions with regards to programming along with most likely going on course(s) as well :)

I am just wondering if there as an easier, less straining way of doing this binary decoding that uses the least amount of memory / resources. Only reason I ask this is because If you have ever come across those 64k graphics demos that do extra ordinary graphics especially for the size of them, then you will know what I am talking about. If not then go to this url and try one or more of them out :

http://www.theprodukkt.com/demoscene.html

^^^ Who ever makes them little programs to do all them graphics, audio , etc is extremely and highly experienced in programming as far as I can tell :)

I thought they were really cool !

Paul,

Thanks for doing the testing.  It helps to have independent verification.

The reason for copying the input parameter to a local variable is that this seems
to run faster than referencing the parameter.  This may have something to do
with heap use and access.  You are welcome to test it both ways (strTemp and bin)

==================================
Option Explicit

Dim LookupTable(0 To &H1111) As Byte

Private Sub Form_Load()
    'LookupTable(&H0) = 0   'not necessary
    'initialize the single dimension lookup table
    'with nibble configurations
       LookupTable(&H1) = 1
      LookupTable(&H10) = 2
      LookupTable(&H11) = 3
     LookupTable(&H100) = 4
     LookupTable(&H101) = 5
     LookupTable(&H110) = 6
     LookupTable(&H111) = 7
    LookupTable(&H1000) = 8
    LookupTable(&H1001) = 9
    LookupTable(&H1010) = 10
    LookupTable(&H1011) = 11
    LookupTable(&H1100) = 12
    LookupTable(&H1101) = 13
    LookupTable(&H1110) = 14
    LookupTable(&H1111) = 15

    Debug.Print BinToStr("010010010010000001110011011100000110010101101110011101000010000000100100001
1000100110000001100000010000001100001011101000010000001010100011010000110100101101110011010110100
01110110010101100101011010110010000001100001011011100110010000100000011000010110110001101100
001000000100100100100000011001110110111101110100001000000111011101100001011100110010000001110
100011010000110100101110011001000000110110001101111011101010111001101111001001000000110110001
101001011011010110100101110100011001010110010000100000011001010110010001101001011101000110100
10110111101101110001000000111010000101101011100110110100001101001011100100111010000101110")

End Sub


Private Function BinToStr(bin As String) As String
    'code borrowed from PaulHews and modified for test
    Dim lngLoop As Long
    Dim Count As Long
    Dim strTemp As String
    Dim bytResult() As Byte
    ReDim b(0 To Len(bin) / 8 - 1)
    strTemp = bin
   
    For lngLoop = 1 To Len(bin) - 7 Step 8
        bytResult(Count) = LookupTable("&h" & Mid$(strTemp, lngLoop, 4)) * 16 + LookupTable("&h" & Mid$(strTemp, lngLoop + 4, 4))
        Count = Count + 1
    Next lngLoop
       
    BinToStr = StrConv(bytResult, vbUnicode)
                       
End Function
Paul,

Some comments and suggestions on your latest code offering:
1. move all the initialization and adjustment checks outside of the
conversion function, most likely to Form_Load.  I know this isn't
standard practice, but I'm trying to squeeze the most performance
out of our code suggestions.  There'll be two*10000 less If statements
executed.

'One time initialization
If Power(7) <> 128 Then

If Len(bin) Mod 8 <> 0 Then

2. replace the If inside the loop with a calculation.
For example, replace
If bytIn(i + j) Xor 48 Then
   bytOut(Count) = bytOut(Count) + Power(7 - j)
End If

with
bytOut(Count) = bytOut(Count) + (bytIn(i + j) Xor 48 ) * Power(7 - j)

3. Use an Integer or Long Integer variable (not part of an array to
store the intermediate power-of-two values.  Referencing the bytOut
array twice per loop can cost you.  After you've finished looping, assign
the sum to the bytOut(Count) position.

4. Set the innermost loop to values that eliminate subsequent addition

5. (optional) You might want to explore any difference it makes to use a byte/integer/Long
variable = 48 to do the XOR rather than the numeric literal.  Performance isn't
always better, but sometimes it is.

Example:

Dim lngSum as Long
Dim intPower as Integer

For i = 0 To Len(bin) - 8 Step 8
  lngSum = 0
  intPower = 7
  For j = i To (i+7)
    lngSum = lngSum + (bytIn(j) Xor 48) * Power(intPower)
    intPower = intPower -1
  Next j
 
  bytOut(Count) = lngSum

Next i
Actually, it comes up about 3 hundredths of a second faster when I don't copy to strTemp... at least on my system.  ..Which
makes sense to me logically as well.  The array lookup is also the fastest, which makes sense as well, although I have to say that I
wouldn't have necessarily guessed that the conversion from "&hxxxx" string to integer wouldn't slow you down some.  :)

Instr lookup 2.28125
Xor 1.8125
collection lookup 1.710938
array lookup 1.253906    
Lol...can we squeeze any more speed out of it?

Definitely some nice code.

I must say I would never have thought of or used the nibble approach myself...

Still trying to digest it... nibble, nibble, byte...
Paul,

Maybe you can use the tweaks I suggested to your code and beat my time.

Off to the races. :-)
Paul & Idle,

Want to see something REALLY SCARY/HAIRY?
If so, do a Google search for Q_20908880

I tackled an NP-Complete problem.  One of the techniques I used
was a direct table lookup in a sparse array.  Of course the arrays
for that problem solution were MUCH bigger than the 4369 bytes
I'm using for the LookupTable array.

Be prepared for a lengthy discussion thread and as many tricks as
I could use.  I've done a few presentations locally on the
NP-Complete Problem/Solution (case study).

========================================
If you look at the NPR stories on today's Morning Edition program,
you will see a link to a Don Knuth interview.  It's so rare to hear/see
any Comp Sci people interviewed in a non-technical media.
Interesting fellow...that Don Knuth:
http://www.npr.org/templates/story/story.php?storyId=4532247

aikimark,

In your profile it says you were a "Software Instructor".  I someday want to teach computer science myself.  =)

Where/how did you teach and do you have any recommendations on how to get there (teaching computer science)?
Idle,

I have done far more mundane teaching than Computer Science teaching.  I teach
in corporate settings, so most topics are practical and skills rather than academic
and theoretical.

If you want to teach, then do the following:
* volunteer to teach some free courses at community centers and churches
* get a good reference or three
* offer to mentor beginners
* participate in local user groups by giving presentations and leading SIGs
* develop some training materials for formal classes (books and sample files)
* begin to network with other trainers (ASTD user groups)
* contact community colleges about teaching
* if you want to do a lot of training, join a training/consulting organization or
  hire someone to find work for you (training sales person).
I made a mistake in timing all these in the IDE instead of compiling and testing that way...  Sometimes it doesn't
make much difference, but in this case, there was a huge difference in performance between the IDE
pseudocode and the compiled code... Well at least I did eventually think to compile it... :)

InstrLookup            1.7813
XorCalc                  0.2031
XorCalcStatic          0.1953
XorCalc2                0.1719
CollectionLookup     1.5000
ArrayLookup           0.9766

The InstrLookup and CollectionLookup are the losers; almost an order of magnitude slower.  The various XorCalc methods are pretty close.  
The optimizations you suggested work for the compiled code, although they slow things down in the IDE...

It proves what we should have known...  That byte arrays rule over any kind of string handling.  (I figure that the implicit string>integer
conversion is what slows down the ArrayLookup.)

The test code has been posted to my website:
http://www11.brinkster.com/notbono/programs.asp

Scroll down to Binary to String to download a zip file with the project and compiled executable.



Hi aikimark , I dont know if this is against EE rules or not however If it is ok with you and the EE rules, is there anyway you could send me an email ? Also I wanted to know since you were a software instructor and did other things as well, I was wondering if you had any contstructive or useful advice you could give me for learning programming, any resources you would recomend with regards to programming whether it be websites or books or pdf files ? I am extremely enthusiastic to learn programming and since you seem to know your stuff and have been a software instructor, etc. I would very much appreciate any info you could give me :)

Thank you so much

Kind regards

Gecko

P.S I am really glad I asked this question now because it seems to be one of the questions that I have asked that has taught me quite a bit as well as being interesting to participate in :)

Gotta love being a part of EE when you get questions like these huh lol.

Idle_Mind - I am just curious where you learnt and have learned all the stuff you know or any suggestions / reccomendations you could make to me as well with regards to what I asked aikimar above.
Paul,

Wonderful testing example.  Thanks.
If I'd been able to do what I wanted to do within a reasonably sized lookup array,
I might have been on par with the XorCalc___ versions.  Good catch with the
Compiled vs. IDE/debug environments.

Also, you might be tempted to tweak the compile options, but the only one that
seems to matter is the Favor Pentium Pro.  Others can actually slow the execution.

===============================
Here is about the closest variation on my original idea that I can create.  It does not
use a lookup table, but rather creates the byte as a direct construction.  It is the
second fastest (behind XorCalc2) on my PC.  Although not the fastest, it does contain
many tricks that can be used to speed up code.  Please add it to the code on your
web site.  Some notes as you read this:
1. CopyMemory allows me to grab 8 bytes of the byte array at a time
2. The dbl_struc structure permits me to have multiple long integer variables
as the target of the CopyMemory subroutine.
3. If I created a long integer array, I could move the entire bytearray with one
CopyMemory call.  I didn't do that this time.
4. The ntohl function is required, since Windows/Intel is a little-endian environment
and I need to preserve the byte order you would see if you did a Hex() function on
the long integers.
5. I had some trouble with the hexmask until I realized that &h30 = 48 ... duh!

* * * CORRECTION TO EARLIER COMMENT * * *
03/14/2005 11:29AM PST comment should read:
  into a structure of two long integer variables
* xor the two long integer values with 808464432 (&h30303030).
  This converts the two possible ASCII values, chr(48)="0" and chr(49)="1",
  into four 00 or 01 bytes.
* use the values in the two long integers to index into the

6. I tried a couple of different ways of directly constructing the bytes.  I've left the
trials in the code below commented out.  The changes made no difference in
performance.
  - I tried using two separate long integer variables instead of the structure variable.  
  - I tried using the XOR function as an alternative to addition

7. Constructing the byte requires 8 AND masks, 8 equality comparisons, and 8 multiplication
operations.  Since the (Windows) True boolean value is -1, I multiplied by the negative of
the number I really wanted.  By combining all of these operations in one statement
I do not encur the overhead of looping.

8. I had to widen the listbox in your sample project and I set the default property of the
command button = True.  This allows me to move the mouse completely off the form and
still launch the test driver code.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'In the General Declarations section of a new module
Type dbl_struc
    High4 As Long
    Low4 As Long
End Type

'In the General Declarations section of the form
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, _
    source As Any, ByVal bytes As Long)

Private Declare Function ntohl Lib "wsock32.dll" (ByVal a As Long) As Long
Private DblLong As dbl_struc
Const hexmask As Long = &H30303030


Public Function DirectConstruction1(bin As String) As String
    Dim lngLoop As Long
    Dim Count As Long
    Dim bytChars() As Byte

'    Dim lngHigh As Long
'    Dim lngLow As Long
   
    Dim bytResult() As Byte
    ReDim bytResult(0 To Len(bin) / 8 - 1)

    bytChars = StrConv(bin, vbFromUnicode)
   
    For lngLoop = 1 To Len(bin) - 7 Step 8
        CopyMemory DblLong, bytChars(lngLoop - 1), 8
        DblLong.High4 = ntohl(DblLong.High4) Xor hexmask
        DblLong.Low4 = ntohl(DblLong.Low4) Xor hexmask
'        lngHigh = ntohl(DblLong.High4) Xor hexmask
'        lngLow = ntohl(DblLong.Low4) Xor hexmask
       
        bytResult(Count) = (((DblLong.High4 And &H1000000) = &H1000000) * -&H80) + (((DblLong.High4 And &H10000) = &H10000) * -&H40) + (((DblLong.High4 And &H100) = &H100) * -&H20) + (((DblLong.High4 And 1) = 1) * -&H10) _
                + (((DblLong.Low4 And &H1000000) = &H1000000) * -&H8) + (((DblLong.Low4 And &H10000) = &H10000) * -&H4) + (((DblLong.Low4 And &H100) = &H100) * -&H2) + (((DblLong.Low4 And 1) = 1) * -&H1)

' = = = = = = = = = = = = = = = =
' = = = = Following Not Used = = = =        
'        bytResult(Count) = (((lngHigh And &H1000000) = &H1000000) * -&H80) + (((lngHigh And &H10000) = &H10000) * -&H40) + (((lngHigh And &H100) = &H100) * -&H20) + (((lngHigh And 1) = 1) * -&H10) _
'                + (((lngLow And &H1000000) = &H1000000) * -&H8) + (((lngLow And &H10000) = &H10000) * -&H4) + (((lngLow And &H100) = &H100) * -&H2) + (((lngLow And 1) = 1) * -&H1)
               
'        bytResult(Count) = (((lngHigh And &H1000000) = &H1000000) * -&H80) Xor (((lngHigh And &H10000) = &H10000) * -&H40) Xor (((lngHigh And &H100) = &H100) * -&H20) Xor (((lngHigh And 1) = 1) * -&H10) _
'                Xor (((lngLow And &H1000000) = &H1000000) * -&H8) Xor (((lngLow And &H10000) = &H10000) * -&H4) Xor (((lngLow And &H100) = &H100) * -&H2) Xor (((lngLow And 1) = 1) * -&H1)
' = = = = Preceding Not Used = = = =        
' = = = = = = = = = = = = = = = =
       
        Count = Count + 1
    Next lngLoop
       
    DirectConstruction1 = StrConv(bytResult, vbUnicode)

End Function
aikimark, can you email me the changed test project?  That way I'll dump it on my site.  Just use the email address on my home page.
...and in case anyone is wondering it is also possible to substitute integer division for
the equality check in the byte construction statement:

        bytResult(Count) = (((DblLong.High4 And &H1000000) \ &H1000000) * &H80) + (((DblLong.High4 And &H10000) \ &H10000) * &H40) + (((DblLong.High4 And &H100) \ &H100) * &H20) + (((DblLong.High4 And 1) \ 1) * &H10) _
                + (((DblLong.Low4 And &H1000000) \ &H1000000) * &H8) + (((DblLong.Low4 And &H10000) \ &H10000) * &H4) + (((DblLong.Low4 And &H100) \ &H100) * &H2) + (((DblLong.Low4 And 1) \ 1) * &H1)


But division doesn't noticably change the performance of the routine relative to XorCalc2.

The problem with taking the lead is my need to address each of the 8 bytes and not being
able to use a lookup table that isn't millions of bytes big.  If I could reduce the number of
calculations I perform in the byte construction statement, I could get close to XorCalc2
performance.
Paul,

Email on its way.  I'd be interested in seeing the performance figures on your PC.
I'm running an AMD 800MHz with Win2000Pro and VB5.  My leaders' test figures
look like:

Test Routine      Run1      Run2      Run3      Avg
----------------------------------------------------------------------
XorCalc2            0.2891      0.2969      0.2891      0.2917
DirectConstr      0.3359      0.3281      0.3281      0.3307
XorCalc            0.3906      0.3828      0.4063      0.393233333
XorCalcStatic      0.3906      0.4063      0.3828      0.393233333

=======================================
Gecko,

I would recommend you find a forum in one of the following EE forums:
* EE Lounge
* Miscellaneous
* Programming

Let me know what suits you best and I will participate in the discussion or
question.  Look for an active forum.  What you want is lots of experts helping
rather than just me.  Maybe Paul or Idle might have some recommendation
on the best forum for your interest.
Programming is my favourite topic, not sure what I would ask because I asked in the past about resources and suggestions and got average responses but since you are or were a software instructor then I think you would have a better idea.

I have a intel P4 3ghz with H/T, 512 MB DDR 400 mhz RAM, 7200 RPM hard drive :) So not sure if that will make it go much faster, also I would need to know how to optimize the IDE / compiler as well as which code or codes you wanted me to test and time. BTW How do you get it to time how long each one takes, do you assign a labels caption to the time it takes  or how does it work ?
I havent recieved any email as of yet :) Any chance you could re send in 5 or 10 mins if I dont get it :) thanks !

~GO
GO,

The email was sent to PaulHews so he could put it up on his web site and more easily
incorporate my project changes.

If you want to see this, visit Paul's web site (see the link he provided).
I must be going blind lol because I couldnt see your email addy on his site. I got a URL to one of my questions YAY ! lol
GO,

You will not find my email address on Paul's web site.
What you WILL find is a link to this discussion thread (which you did find),
a link for a zip file containing the VB project and a compiled version of the
program.  You will also find an email link for Paul (not me).
oh ok, what did you think to my abriev GO, I just made that just as a joke cos I see people on here make abrievs for there nicks, I think Idle Mind was IM ( which in chat terminology means Instant Message) lol, sounds just like him LOL.

Anyway, If I did what IM Did then I would be GA , I think GO is still good but just wanted opinions on it :)
I eliminated six of the multiplication operations in my construction, and still
didn't manage to catch up to to the XorCalc2 leader.  In the following byte
construction statement, the difference of the exponents (maskbit - targetbit)
is the divisor.  This is exponent math.

        bytResult(Count) = (((DblLong.High4 And &H1000000) \ &H20000)) + (((DblLong.High4 And &H10000) \ &H400)) + (((DblLong.High4 And &H100) \ &H8)) + (((DblLong.High4 And 1)) * &H10) _
                + (((DblLong.Low4 And &H1000000) \ &H200000)) + (((DblLong.Low4 And &H10000) \ &H4000)) + (((DblLong.Low4 And &H100) \ &H80)) + (((DblLong.Low4 And 1)) * &H1)
gecko,

If GO is a joke then I'll refrain from using it.  If you want to use it as
your 'handle', then I have no problem addressing you that way...
Whatever makes you happy.  It doesn't matter to me.

One thing I would add is that "GO" is also a T-SQL command.  Be
careful about using that handle if you participate in the SQL Server
forum.
I've updated the project on my site.  
Thanks Paul.

I found one redundant multiplication operation for the low-order bit.  
I removed it in the statement below.  I just sent you an email with this
statement as well.  I didn't know if you'd received the email.

       bytResult(Count) = (((DblLong.High4 And &H1000000) \ &H20000)) + (((DblLong.High4 And &H10000) \ &H400)) + (((DblLong.High4 And &H100) \ &H8)) + (((DblLong.High4 And 1)) * &H10) _
                + (((DblLong.Low4 And &H1000000) \ &H200000)) + (((DblLong.Low4 And &H10000) \ &H4000)) + (((DblLong.Low4 And &H100) \ &H80)) + (DblLong.Low4 And 1)

=========================
Not included in the code base was a different attempt to do a comparison of nibble values.
I used two Select Case statements and combined the associated low-order and high-order
nibble bit configurations into the byte for that iteration.  It wasn't qhite as fast as the
DirectConstruction1 routine.  If you want it, I'll send it to you.

Optimization Tip:
If you know the frequency of values, order the Select Case statment's Case clauses to
check for the most likely values first.  This minimizes the number of unsuccessful
value comparisons in the Select Case statement.
Example:
* For this test, I know that the decoded string is an English language sentence with mixxed
case aphabetic letters.  To optimize the Select Case statement for this highorder nibble,
I placed the lower case nibble values at the top and then the upper case nibble values,
and then the rest of the possible values.
* Since the low order nibbles values are evenly distributed, there was no advantage to
change the arrangement of the Case clauses.

==================================
I think this just about wraps up this discussion and test.  
Thanks to all.  This has been fun.

If you want to read about more VB performance enhancement, visit the VBSpeed site:
http://www.xbeat.net/vbspeed/index.htm

Individual statements and common techniquest are discussed.  Performance tests
are compared.  Maybe they would be interested in your link, Paul.  As far as I'm
concerned, they are welcome to the source code.  

They do have a page dedicated to a String-to-Bit conversion.
http://www.xbeat.net/vbspeed/c_StringToBit.htm

I think we have three different approaches that might be of interest to the VBSpeed
folks and warrant inclusion and (their) official testing.
Actually, the StringToBit page is dedicated to the opposite task of what we have
done and complements our work nicely.
http://www.xbeat.net/vbspeed/c_StringToBit.htm
ok thanks for the warning aikimark, I dont use SQL that much so I dont really participate in them that much but feel free to use GO as my handle :)

>> Idle_Mind - I am just curious where you learnt and have learned all the stuff you know or any suggestions / reccomendations you could make to me as well with regards to what I asked aikimar above.

I'm principally a self-taught programmer since I was about 10 years old.  My dad was a computer programmer and we always had computers in the house.  I just picked it up and ran with it...

I've got 3/4ths of a CS degree done but I find it really hard to attend classes and pay attention because they move so s...l...o...w and don't challenge me in any way.  Maybe some day I'll go back and finish that silly degree...

As far as recommendations just always be open to different approaches and try to learn from others code.  Subscribe to questions that you don't know the answer to but are interested in so you can watch the answers unfold.  Answer the mundane questions...nothing can be substitued for actually doing the coding.  You should be able to see how different parts of a problem would be broken down and what kind of structure would be appropriate.  (String vs. Array, For..Next vs. While...Wend, Global Flag vs. Events, etc...) This just comes from experience and having to write code to solve common problems over and over...  Decomposition of a problem is the most important part and is where most developers get themselves into trouble.  If you can break problems down until you can see simple subs/functions that do ONE thing and that ONE thing WELL then you are in good shape.  You will have an easy to read and easy to maintain application.  The big picture becomes clearer as you write the small pieces and they fit together nicely like a jigsaw puzzle.  Always concern yourself with solving the problem first and making an interface (GUI) for it second.  Separation of engine and GUI is also difficult for many programmers.  If you can take your concept and move it to another application easily then you have done well.  

If you have VB.net, you really should spend some time trying to answer questions and looking at solutions in the VB.Net area.  VB6 is an OOP mutt and not really the best choice for good design building habits.  You will see completely different approaches to problems in the VB.Net area because the structure and capabilities of .Net are very different from that of VB6.
https://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/
That is my intention with regards to moving onto another language which is OOP and I am aware of vb 6 not being OOP well at least not fully. I want to get a full understanding of concepts and principles of programming with regards to everything from WMI, API's, subs, functions, variables, etc , etc. So that when I move on from visual basic 6 I have a good base / grounding so that moving on to the next level / step IE .NET and the framework and C# or C++ or even Java that I have a basic understanding of what I am doing when I am programming. If that makes any sense, not sure if that is a good way to go about it either but that is how I am approaching it, unless you have any better ideas with regards to doing it in a more structured way or if you just reccomend going straight onto .NET ? Anyway thanks ~IM :D