Delphi - Чистые элементы TListBox - PullRequest
2 голосов
/ 22 апреля 2010

Я хочу очистить список, сверяя его с двумя другими списками.

  • Listbox1 будет иметь большой список элементов
  • Listbox2 будет содержать слова, которые я хочу удалить из listbox1
  • Listbox3 будет иметь обязательные слова, которые должны существовать, чтобы он оставался в listbox1

Ниже приведен код, который у меня есть для этого, он ОЧЕНЬ медленный с большими списками.

// 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;

Ответы [ 2 ]

4 голосов
/ 22 апреля 2010

Если вы делаете все, что зацикливается с экземпляром TStrings в элементе управления, может быть полезно создать временный экземпляр TStringList, назначить ему элементы управления, а затем использовать временный список.

Причина этого заключается в том, что свойство Items в списке, поле со списком или тому подобном реализуется через прокси-класс, который не содержит сами строки, но использует для извлечения сообщения Windows, такие как LB_GETCOUNT и LB_GETTEXT.элементы прямо из родного элемента управления Windows.Если вы обращаетесь к элементу списка строк несколько раз, накладные расходы на повторную обработку сообщений будут складываться.

3 голосов
/ 22 апреля 2010

Если это работает со списком, вероятно, каждый раз требуется много времени, чтобы перекрасить все.Вы можете отключить это поведение.Окружите внешний цикл следующим образом:

listbox.Items.BeginUpdate;
try
  //do the loop here
finally
  listbox.Items.EndUpdate;
end;

Кроме того, вы можете назначить логическое значение непосредственно для вычисления логического выражения, что сэкономит некоторое время на вашем внутреннем цикле.Итак:

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;

Не уверен, сколько из этого будет иметь значение.Если вы вносите эти изменения, но они все еще слишком медленные, попробуйте запустить вашу программу через профилировщик, такой как Sampling Profiler , который поможет вам увидеть, на что ваш код тратит большую часть своего времени.

...