5
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Firstly, are you using .NET or not? \$\endgroup\$ – Grant Thomas Apr 24 '11 at 12:55
  • \$\begingroup\$ The code is in VB, but i know .NET, and the speed is slow in .vb.net too :( \$\endgroup\$ – Sourav Apr 24 '11 at 12:57
  • \$\begingroup\$ 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. \$\endgroup\$ – Grant Thomas Apr 24 '11 at 13:04
  • \$\begingroup\$ exactly which part to rewrite ? \$\endgroup\$ – Sourav Apr 24 '11 at 15:59
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Grant Thomas Apr 24 '11 at 16:14
5
\$\begingroup\$

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")
\$\endgroup\$
  • \$\begingroup\$ after testing i'll post \$\endgroup\$ – Sourav Apr 25 '11 at 14:27
  • \$\begingroup\$ you might want to consider IndexOf(f,StringComparison.InvariantCulture) depending on what's going to be in those strings \$\endgroup\$ – Conrad Frix Apr 25 '11 at 20:42
1
\$\begingroup\$

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
        'Do your stuff here
    End If

End Sub
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.