Reputation: 2237
I want to clean a list box by checking it against two other list boxes.
Below is the code I've got so far for this, it's VERY slow with large lists.
// not very efficient
Function checknegative ( instring : String; ListBox : TListBox ) : Boolean;
Var
i : Integer;
Begin
For I := listbox.Items.Count - 1 Downto 0 Do
Begin
If ExistWordInString ( instring, listbox.Items.Strings [i],
[soWholeWord, soDown] ) = True
Then
Begin
result := True; //True if in list, False if not.
break;
End
Else
Begin
result := False;
End;
End;
result:=false;
End;
Function ExistWordInString ( aString, aSearchString : String;
aSearchOptions : TStringSearchOptions ) : Boolean;
Var
Size : Integer;
Begin
Size := Length ( aString );
If SearchBuf ( Pchar ( aString ), Size, 0, 0, aSearchString, aSearchOptions ) <> Nil Then
Begin
result := True;
End
Else
Begin
result := False;
End;
End;
Upvotes: 2
Views: 2137
Reputation: 32334
If you do anything that loops with a TStrings
instance in a control it may be beneficial to create a temporary TStringList
instance, assign the control items to it, then use the temporary list.
The reason for that is that the Items
property in a list box, combo box or similar is implemented via a proxy class that doesn't hold the strings itself, but which uses Windows messages like LB_GETCOUNT
and LB_GETTEXT
to retrieve the elements directly from the native Windows control. If you access a string list item several times then the overhead of the repeated message handling will add up.
Upvotes: 4
Reputation: 84550
If this is working on a listbox, it's probably taking a lot of time to repaint everything every time. You can disable this behavior. Surround the outermost loop with this:
listbox.Items.BeginUpdate;
try
//do the loop here
finally
listbox.Items.EndUpdate;
end;
Also, you can assign a boolean directly to the evaluation of a boolean expression, which will save some time on your inner loop. So:
Function ExistWordInString ( aString, aSearchString : String; aSearchOptions : TStringSearchOptions ) : Boolean;
Var
Size : Integer;
Begin
Size := Length ( aString );
result := SearchBuf ( Pchar ( aString ), Size, 0, 0, aSearchString, aSearchOptions ) <> Nil;
End;
Not sure how much of a difference that will make, though. If you make these changes and it's still too slow, try running your program through a profiler such as Sampling Profiler, which will help you see what your code is spending most of its time doing.
Upvotes: 3