Same String?
|
How do you test whether two strings are identical?
You probably use the equal operator: If String1 = String2 Then ...
Nothing could be easier, but is it fast?
|
|
Code |
EqualOperator |
fRet = (sDum1 = sDum2)
|
StrComp |
fRet = (StrComp(sDum1, sDum2, vbBinaryCompare) = 0)
|
InStrB |
' by Donald, donald@xbeat.net, 20001011, rev 001 20040813
If LenB(sDum1) = LenB(sDum2) Then
If LenB(sDum1) = 0 Then
fRet = True
Else
fRet = (InStrB(1, sDum1, sDum2, vbBinaryCompare) <> 0)
End If
End If
|
lstrcmp |
Public Declare Function lstrcmp Lib "kernel32" Alias "lstrcmpA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
fRet = (lstrcmp(sDum1, sDum2) = 0)
|
IsSameString01 |
fRet = IsSameString01(sDum1, sDum2)
Public Function IsSameString01(String1 As String, _
String2 As String) As Boolean
' by Donald, donald@xbeat.net, 20001011, rev 001 20040813
If LenB(String1) = LenB(String2) Then
If LenB(String1) = 0 Then
IsSameString01 = True
Else
IsSameString01 = (InStrB(1, String1, String2, vbBinaryCompare) <> 0)
End If
End If
End Function
|
IsSameString02 |
IsSameString02 is wrapped in a class.
Cinemascope here, preview here:
|
Calls |
1 | both strings 1000 chars, all chars equal
|
2 | both strings 1000 chars, first char differs
|
3 | both strings 1000 chars, last char differs
|
4 | 1000 vs. 999 chars, all chars equal
|
|
VB5 Charts |
|
Call 1 |
4 | 1.30 | 12µs |
5 | 1.31 | 12µs |
2 | 1.02 | 9µs |
6 | 18.36 | 166µs |
3 | 1.02 | 9µs |
1 | 1.00 | 9µs |
|
Call 2 |
5 | 1.27 | 0.304µs |
4 | 1.22 | 0.293µs |
2 | 1.03 | 0.247µs |
6 | 607.34 | 145.770µs |
3 | 1.17 | 0.281µs |
1 | 1.00 | 0.240µs |
|
Call 3 |
5 | 1.37 | 11.929µs |
4 | 1.36 | 11.888µs |
2 | 1.12 | 9.727µs |
6 | 19.03 | 166.008µs |
3 | 1.12 | 9.761µs |
1 | 1.00 | 8.723µs |
|
Call 4 |
5 | 158.18 | 11.815µs |
4 | 157.87 | 11.791µs |
1 | 1.00 | 0.075µs |
6 | 2,222.27 | 165.984µs |
2 | 1.50 | 0.112µs |
3 | 2.15 | 0.161µs |
|
|
VB6 Charts |
|
Call 1 |
2 | 1.32 | 11.809µs |
3 | 1.32 | 11.822µs |
4 | 2.61 | 23.367µs |
6 | 18.57 | 166.165µs |
5 | 2.62 | 23.403µs |
1 | 1.00 | 8.947µs |
|
Call 2 |
4 | 1.37 | 0.305µs |
5 | 1.47 | 0.327µs |
2 | 1.12 | 0.250µs |
6 | 654.20 | 145.559µs |
3 | 1.27 | 0.282µs |
1 | 1.00 | 0.222µs |
|
Call 3 |
3 | 1.34 | 11.974µs |
2 | 1.34 | 11.971µs |
4 | 2.62 | 23.476µs |
6 | 18.55 | 166.195µs |
5 | 2.63 | 23.562µs |
1 | 1.00 | 8.961µs |
|
Call 4 |
4 | 186.39 | 11.801µs |
5 | 186.53 | 11.809µs |
1 | 1.00 | 0.063µs |
6 | 2,613.35 | 165.451µs |
2 | 1.73 | 0.109µs |
3 | 2.28 | 0.144µs |
|
|
Notes & Conclusions |
- The equal operator is not very fast (at string comparison)! Looking at the numbers, you see that it compares strings left to right and that it's smart enough to quit comparing when it spots the first difference. However, it's too dumb to first do the most obvious test: comparing the lengths of the strings! Call 4 reveals the catastrophic results of this.
- Looking at Call 1 and Call 3 (VB5 Charts), you see that the equal operator is so bad that it even loses against a function call to IsSameString01!
This, however, is no more the case under VB6: sadly enough, the InStr/InStrB function got much slower under VB6 when the scanning has to go a long way (Call 1 and Call 3)!
- The StrComp function does not make a difference here. Note, however, that it's a bit faster than the equal operator with shorter strings!
- By the way, I'm using LenB and InStrB because they are a bit faster than Len and InStr.
- The lstrcmp API has some problem here. Can anybody tell me what's going on? Yes: "When you Declare an API call with As String parameters, VB converts the strings from Unicode to ANSI before it makes the call. This explains lstrcmp's poor performance." (Aidan Corey, aidan.corey@pas.co.uk). (See also Appleman Win32API, p. 44)
The bottom line is:
- Just forget about the equal operator and use IsSameString02 to compare strings of the same length, and InStrB if your strings are likely to differ in length.
|
Got comments? |
 |
|