Reputation: 5959
Am trying to make my vb6 app run faster, the reason is that am populating vbaccelerators sgrid with about 10k items all at once (this is a requirement from client).
I had to populate about 20 columns for each of the 10k items, and i have to perform string comparison in about more than half of them, so i wrote a string comparison function and did profiling
Function IsEqual(byval value1 as string, Byval value2 as string) as boolean
' content, various versions are below
End function
currently the items = 5000 and each of the time below shows the time it took and various versions of the function:
LCase$(Value1) = LCase$(value2)
time: 29149 ms
(StrComp(Value1, value2, 1) = 0 )
time: 30836 ms
If StrComp(Value1, value2, 1) = 0 Then
IsEqual = True
Else
IsEqual = False
End If
time 34180 ms
If StrComp(Value1, value2, 1) = 0 Then IsEqual = True
time 28387 ms
Timing is done with:
Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Declare Function timeGetTime Lib "winmm.dll" () As Long
which returns the time in milliseconds.
Is there anyway to make the comparison faster?
Upvotes: 2
Views: 9625
Reputation: 11
This should be pretty fast.
Option Explicit
Private Declare Sub DerefByte Lib "msvbvm60" Alias "GetMem1" (ByVal Add As Long, ByRef Value As Byte)
Private Declare Sub DerefLong Lib "msvbvm60" Alias "GetMem4" (ByVal Add As Long, ByRef Value As Long)
Private Sub Form_Load()
Debug.Print IsEqual("Hello", "hello")
Debug.Print IsEqualB("Hello", "hello")
End Sub
Public Function IsEqualB(Str1 As String, Str2 As String) As Boolean
Dim lpS1 As Long, lpS2 As Long
Dim t1 As Byte, t2 As Byte
Dim lSz As Long
Dim i As Long
IsEqualB = True
lpS1 = StrPtr(Str1)
lpS2 = StrPtr(Str2)
DerefLong lpS1 - 4, lSz
If lSz = LenB(Str2) Then
For i = 0 To lSz - 1 Step 2
DerefByte lpS1 + i, t1
DerefByte lpS2 + i, t2
If Not (t1 = t2) Then
IsEqualB = False
Exit For
End If
Next
Else
IsEqualB = False
End If
End Function
Public Function IsEqual(Str1 As String, Str2 As String) As Boolean
Dim lpS1 As Long, lpS2 As Long
Dim t1 As Byte, t2 As Byte
Dim lSz As Long
Dim i As Long
IsEqual = True
lpS1 = StrPtr(Str1)
lpS2 = StrPtr(Str2)
DerefLong lpS1 - 4, lSz
If lSz = LenB(Str2) Then
For i = 0 To lSz - 1 Step 2
DerefByte lpS1 + i, t1
DerefByte lpS2 + i, t2
If Not (t1 Or &H20) = (t2 Or &H20) Then
IsEqual = False
Exit For
End If
Next
Else
IsEqual = False
End If
End Function
The basic premise here is to do byte by byte comparison mod 2 over the Unicode strings. One of the above functions is case sensitive, IsEqualB, then other is insensitive IsEqual.
Of course, it uses a couple of undocumented functions in the Visual Basic 6 runtime: but if you want speed, that's what you have to do, unfortunately.
Upvotes: 1
Reputation: 115
look at the LockWindowUpdate() WinAPI call. This can really help grids when you are populating them . Make sure you call it once to lock the window and once to unlock it.
Upvotes: 0
Reputation: 24506
You can probably cut your execution time in half by using "OPTION COMPARE TEXT". Place this line at the top of your code module.
OPTION COMPARE TEXT
This line, when used, will cause string compare within the code module be case insensitive. Because of this, you can simply use:
Function IsEqual(byval value1 as string, Byval value2 as string) as boolean
IsEqual = (Value1 = Value2)
End Function
Upvotes: 0
Reputation: 2354
Things that might improve performance include..
Upvotes: 2
Reputation: 10452
Have you tried:
Function IsEqual(byval value1 as string, Byval value2 as string) as boolean
Return StrComp(LCase$(Value1), LCase$(value2), vbBinaryCompare) = 0
End function
Upvotes: 0