# VB6: String Searching Performance

5 years ago, when i was in love with VB, I created this simple program to detect if a file is virus or not.

What I'd like is to see if you can help me optimize it, speed-wise.

I open an executable file in a rich textbox control and use the Instr method to search for occurrences of predefined string. The problem is that the Instr method is damn slow when searching files as small as 512KB.

Can the speed be enhanced?

If InStr(1, rt.Text, "scripting.filesystemobject") Then
It does something with FSO
End If

If InStr(1, rt.Text, "thisprogramcannotberunindosmode") Or InStr(1, rt.Text, "thisprogrammustberununderwin32") Then
Probably a DOS program
Else
looks like a GUI program
End If

If InStr(1, rt.Text, "hkey_local_machine") Then
Does something with registry
End If
If InStr(1, rt.Text, "hkey_users") Then
Does something with registry
End If
If InStr(1, rt.Text, "hkey_current_user") Then
Does something with registry
End If
If InStr(1, rt.Text, "hkey_classes_root") Then
Does something with registry
End If
If InStr(1, rt.Text, "hkey_current_config") Then
Does something with registry
End If

• Firstly, are you using .NET or not? Apr 24 '11 at 12:55
• The code is in VB, but i know .NET, and the speed is slow in .vb.net too :( Apr 24 '11 at 12:57
• What code in VB.NET did you try? if the same code, then nothing is really going to change, is it? If you're using VB.NET, do your best to avoid mixing old VB usage in there. i.e. the code should be re-written for .NET. Apr 24 '11 at 13:04
• exactly which part to rewrite ? Apr 24 '11 at 15:59
• By that very question I think we can conclude that you don't know VB.NET. You just compiled legacy VB code using the VB.NET compiler so it would run in a managed environment - this is (just one reason) why I seriously dislike VB.NET. Apr 24 '11 at 16:14

In VB2010 the instr out performed indexof

    Dim ipsum As String = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

Dim tries As Integer = 100000
Dim stpw As New Stopwatch
Dim iof As Integer
Dim f As String = "sint"

stpw.Reset()
stpw.Start()

For x As Integer = 1 To tries
iof = ipsum.IndexOf(f)
Next
stpw.Stop()
Label1.Text = stpw.ElapsedMilliseconds.ToString("n2")

stpw.Reset()
stpw.Start()

For x As Integer = 1 To tries
iof = InStr(ipsum, f)
Next
stpw.Stop()
Label2.Text = stpw.ElapsedMilliseconds.ToString("n2")

• after testing i'll post Apr 25 '11 at 14:27
• you might want to consider IndexOf(f,StringComparison.InvariantCulture) depending on what's going to be in those strings Apr 25 '11 at 20:42

I have barely tested this at all, and this code is in and of itself not a complete solution, but I thought I'd offer an entirely different approach. (It may not be faster in practice, but I'm trying to think outside the box...)

Would you be able to take every word in rt.Text (whitespace/punctuation delimited) and plug those words into a Scripting.Dictionary? The search for your key terms in the dictionary should be very fast, assuming the reading in to the dictionary in the first place is any faster.

This is formed from VBA, but you should get the concept:

Sub Test()

Dim sSource As String
Dim sSplitText() As String
Dim dictAllWords As New Scripting.Dictionary
Dim i As Integer

sSource = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

sSource = Replace(sSource, ",", " ") ' Repeat for other punctuation and whitespace...

sSplitText = Split(sSource, " ")

For i = 0 To UBound(sSplitText)
If Not dictAllWords.Exists(sSplitText(i)) Then dictAllWords.Add sSplitText(i), sSplitText(i)
Next i

If dictAllWords.Exists("consectetur") Then