Shane Russell
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 !!
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
* 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
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 !
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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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.
>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.
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.
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.
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...
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... =)
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...
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.
* 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.
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 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
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
ASKER
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 !
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("0100100100100000 0111001101 1100000110 0101011011 1001110100 0010000000 100100001
10001001100000011000000100 0000110000 1011101000 0100000010 1010001101 0000110100 1011011100 1101011010 0
01110110010101100101011010 1100100000 0110000101 1011100110 0100001000 0001100001 0110110001 101100
00100000010010010010000001 1001110110 1111011101 0000100000 0111011101 1000010111 0011001000 0001110
10001101000011010010111001 1001000000 1101100011 0111101110 1010111001 1011110010 0100000011 0110001
10100101101101011010010111 0100011001 0101100100 0010000001 1001010110 0100011010 0101110100 0110100
10110111101101110001000000 1110100001 0110101110 0110110100 0011010010 1110010011 1010000101 110")
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
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("0100100100100000
10001001100000011000000100
01110110010101100101011010
00100000010010010010000001
10001101000011010010111001
10100101101101011010010111
10110111101101110001000000
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
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
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...
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. :-)
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.
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)?
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 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.
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.
ASKER
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.
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
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.
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.
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.
ASKER
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 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 ?
ASKER
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
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).
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).
ASKER
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).
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).
ASKER
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 :)
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)
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.
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.
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
done and complements our work nicely.
http://www.xbeat.net/vbspeed/c_StringToBit.htm
ASKER
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/
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/
ASKER
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
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-
"1000-1001-1010-1011-1100-
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