DWUTKA at marlow.com
DWUTKA at marlow.com
Mon Oct 31 11:49:09 CST 2005
My my my, you lean something new everyday! I never realized that Mid was a function that you could 'set', like Date(), and Time() Go figure. Working with the byte array is just as fast. And with my encryption routine, it was even faster then actually working with the string, because I was dealing with the ascii values anyways, so using the byte array, I didn't have to do any conversion back and forth. Drew -----Original Message----- From: Gustav Brock [SMTP:Gustav at cactus.dk] Sent: Monday, October 31, 2005 11:38 AM To: accessd at databaseadvisors.com Subject: Re: [AccessD] New Wheel Encryption Add-in Hi Drew Those examples are the two extremes. In between you have Mid() used this way where you have created a string of the final length and then replace this char by char with the encrypted string. ' Perform high speed insertion of encrypted character. Mid(strEncrypted, lngN, 1) = Chr(c) It has the advantage that it is a few lines of code only. But perhaps you should move the entire encryption routine to a C++ dll as you can read from the recent postings from Shamil. /gustav >>> DWUTKA at marlow.com 31-10-2005 10:28:07 >>> In the process of optimizing the code, I also had to overcome the obstacle of string 'recombination'. VB.Net has a class to do this, but I am creating my big project in VB 6.0. Strings are easy to deal with, but if you are tearing them apart, and rebuilding them, that can be time consuming. Take for example this routine (sorry for the horrible naming convention....this is just an example): Private Sub Command3_Click() Dim strTemp As String Dim strTemp2 As String Dim i As Long Dim dtStart As Date strTemp = String(100000, "A") strTemp2 = "" dtStart = Now For i = 1 To Len(strTemp) strTemp2 = strTemp2 & LCase(Mid(strTemp, i, 1)) Next i MsgBox Format(Now - dtStart, "HH:NN:SS") MsgBox strTemp2 End Sub In the code above, on my 800 mhz machine, I get 34 seconds. Note that we don't start 'timing' until we get into the loop. The string function, which in this case, is creating a string 100,000 characters long, of all A's, is neglible anyways. However, the For Next loop is where we are going to process the first string, and build the second string with the 'processed' characters. In this case, we are simply getting the lower case version of the character. (Yes, I know, we could just Lcase the whole first string, but that isn't the point. What if we are swapping characters (such as in my encryption routine)? Anyhow, the time we are taking isn't in the Lcase and Mid statements, it's in the strTemp2=strTemp2 & part. Initial, that process screams. Add a debug.print statement of 'i' and you'll see what I mean. It will rocket through the beginning, but as strTemp2 gets bigger and bigger, it will get slower and slower. So how do we speed that up? Arrays...byte arrays, to be specific, with a simple API call, CopyMemory. Take a look at the code below: Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Sub Command4_Click() Dim strTemp As String Dim strTemp2 As String Dim tmpArray() As Byte Dim i As Long Dim dtStart As Date strTemp = String(100000, "A") ReDim tmpArray(1 To Len(strTemp)) strTemp2 = "" dtStart = Now CopyMemory tmpArray(1), ByVal strTemp, Len(strTemp) For i = 1 To Len(strTemp) tmpArray(i) = Asc(LCase(Chr(tmpArray(i)))) Next i strTemp2 = StrConv(tmpArray, vbUnicode) MsgBox Format(Now - dtStart, "HH:NN:SS") MsgBox strTemp2 End Sub Same process, with two steps added. Before we start 'timing', we do redimension the byte array, but, I did include the copymemory statement within the 'timed' portion. That's the first step we added. CopyMemory. Note that the first argument is what we are copying into (and we have to refer to the first item in the array, not just the array itself), then the next argument is the string we want to copy into the array (using the ByVal statement, some API's are fun like that), then we tell it how much of the string we want to copy. (Because we could copy just a part if we want....warning, copying more then is there will crash the VBE....). The second part we added is the strConv line. Where we convert the byte array back into a string. We also modified the 'processing' that is being done, because the byte array is going to represent the ASCII values of a string, not the text itself. But the same process is in place (we are converting the ASCII byte to a character, then setting it to lowercase, and then converting it back to ascii). All the added steps, I wonder how fast it will be, well, on the same machine we got 34 seconds for on the first routine, we get 0 seconds for this routine. Same processing results, and that 0 seconds pops up instantaneously. Quite a performance increase, I'd say. -- AccessD mailing list AccessD at databaseadvisors.com http://databaseadvisors.com/mailman/listinfo/accessd Website: http://www.databaseadvisors.com