InStr performance

M

Morten Snedker

Scenario:
From a given folder all files from all subdirs are read. These are
dropped in a one-dimensional array - myArray.

Once everything is in my array it is sorted and dropped in a listbox.

In a textbox I can enter a search criteria. Each time I press a key
the listbox is cleared and I run this code (at this point the listbox
is cleared), which fills to another array - subArray:

iLB = myArray.GetLowerBound(0)
iUB = myArray.GetUpperBound(0)

For i = iLB To iUB
If Not str = Nothing Then
If InStr(1, str, Me.txtSearch.Text,
CompareMethod.Text) > 0 Then
ReDim Preserve subArray(intSubArray)
subArray(intSubArray) = str
intSubArray += 1
End If
End If
Next


So, I see if the string in the textbox is in the string of each index
in my array. This runs fine when having less than 1000 files/indexes.
But in some cases I have more than 6000 thousand indexes, which makes
running through the array too slow.

I could demand a minium of characters to be entered before performing
my search, but I rather want to know if I could do something
differently to speed up the process?

Is InStr the wrong method? Is the array an improper method? In time my
app will be running against an SQL-Server - perhaps saving to a
tmp-table instead of an array would be better?


Thanks for any input as well as time spend on this! =B-)


Regards /Snedker
 
K

Ken Tucker [MVP]

Hi,

If you are searching the listbox for the start of a string Iwould
use the listbox's findstring method.

http://msdn.microsoft.com/library/d...mwindowsformslistboxclassfindstringtopic2.asp

For searching a string I would the string's indexof method.

http://msdn.microsoft.com/library/d.../html/frlrfsystemstringclassindexoftopic4.asp

If it the listbox is bound to a datasource I would use the
dataview's find method.

http://msdn.microsoft.com/library/d...ml/frlrfsystemdatadataviewclassfindtopic2.asp

http://msdn.microsoft.com/library/d...en-us/cpguide/html/cpconsearchingdataview.asp

Ken
----------------------
"Morten Snedker" <morten_spammenot_ATdbconsult.dk> wrote in message
Scenario:
From a given folder all files from all subdirs are read. These are
dropped in a one-dimensional array - myArray.

Once everything is in my array it is sorted and dropped in a listbox.

In a textbox I can enter a search criteria. Each time I press a key
the listbox is cleared and I run this code (at this point the listbox
is cleared), which fills to another array - subArray:

iLB = myArray.GetLowerBound(0)
iUB = myArray.GetUpperBound(0)

For i = iLB To iUB
If Not str = Nothing Then
If InStr(1, str, Me.txtSearch.Text,
CompareMethod.Text) > 0 Then
ReDim Preserve subArray(intSubArray)
subArray(intSubArray) = str
intSubArray += 1
End If
End If
Next


So, I see if the string in the textbox is in the string of each index
in my array. This runs fine when having less than 1000 files/indexes.
But in some cases I have more than 6000 thousand indexes, which makes
running through the array too slow.

I could demand a minium of characters to be entered before performing
my search, but I rather want to know if I could do something
differently to speed up the process?

Is InStr the wrong method? Is the array an improper method? In time my
app will be running against an SQL-Server - perhaps saving to a
tmp-table instead of an array would be better?


Thanks for any input as well as time spend on this! =B-)


Regards /Snedker
 
M

Mattias Sjögren

I could demand a minium of characters to be entered before performing
my search, but I rather want to know if I could do something
differently to speed up the process?

Stop using ReDim. Try using for example an ArrayList instead.



Mattias
 
H

Herfried K. Wagner [MVP]

Morten,

Morten Snedker said:
From a given folder all files from all subdirs are read. These are
dropped in a one-dimensional array - myArray.

Once everything is in my array it is sorted and dropped in a listbox.

In a textbox I can enter a search criteria. Each time I press a key
the listbox is cleared and I run this code (at this point the listbox
is cleared), which fills to another array - subArray:

iLB = myArray.GetLowerBound(0)
iUB = myArray.GetUpperBound(0)

For i = iLB To iUB
If Not str = Nothing Then
If InStr(1, str, Me.txtSearch.Text,
CompareMethod.Text) > 0 Then
ReDim Preserve subArray(intSubArray)
subArray(intSubArray) = str
intSubArray += 1
End If
End If
Next


So, I see if the string in the textbox is in the string of each index
in my array. This runs fine when having less than 1000 files/indexes.
But in some cases I have more than 6000 thousand indexes, which makes
running through the array too slow.

'ReDim Preserve' is a very costly operation because it will create a new
array of the desired size and copy the data from the old array to the new
array. You can either use a dynamic data structure like an 'ArrayList' or
'StringCollection' to store the strings matching with the criteria or use
the technique shown in the sample below:

\\\
Dim astr1() As String = _
{"Bla", "Habla", "Foo", "Blabbel", "Goo", "Foblaa"}
Dim astr2() As String = _
FilterStringArray(astr1, "Bla")
For Each s As String In astr2
Debug.WriteLine(s)
Next s
..
..
..
Public Function FilterStringArray( _
ByVal Strings() As String, _
ByVal Filter As String _
) As String()
Dim Result(Strings.Length - 1) As String
Dim n As Integer
For Each s As String In Strings
If InStr(s, Filter, CompareMethod.Text) > 0 Then
Result(n) = s
n = n + 1
End If
Next s
ReDim Preserve Result(n - 1)
Return Result
End Function
///
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top