Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi ListView - Suche sehr langsam (https://www.delphipraxis.net/83437-listview-suche-sehr-langsam.html)

Dash 2. Jan 2007 20:59


ListView - Suche sehr langsam
 
Hallo,

ich habe mir gerade eine kleine Suche zusammengebaut, funktioniert auch recht gut bis auf 2 "kleinere" Schwierigkeiten.

1. Die Suche ist bei > 1000 ~ Einträgen sehr langsam. Da ich > 10000 Einträge habe, ist mir das Suchen definitiv zu langsam.
2. Wenn ein Eintrag automatisch über meine Suche markiert wird, wird nicht automatisch zum Eintrag hingescrollt.

Hier mein Code:

Delphi-Quellcode:
procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ListView1.Items.Count - 1 do
  begin
    if pos(ansiuppercase(LabeledEdit1.Text), ansiuppercase(ListView1.Items[i].SubItems.Text)) <> 0 then
    begin
      ListView1.HideSelection := False;
      ListView1.ItemIndex := i;
    end;
  end;
end;
Das gesucht wird wenn was neues im LabeledEdit eingegeben wird möchte ich schon gerne so behalten, da es so am bequemsten ist.

Gruß
Dash

Bernhard Geyer 2. Jan 2007 21:02

Re: ListView - Suche sehr langsam
 
Jeder Vergleich erfordert 2 mal ein ansiuppercase.
Einen Vergleich kannst Du dir ersparen indem du das Ergebnis von
Delphi-Quellcode:
ansiuppercase(LabeledEdit1.Text)
in einer Hilfsvariable speicherst

Muetze1 2. Jan 2007 21:04

Re: ListView - Suche sehr langsam
 
Delphi-Quellcode:
procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
  i: Integer;
  lTemp: String;
  lItem: TListItem;
begin
  lTemp := AnsiUpperCase(LabeledEdit1.Text);

  for i := 0 to Pred(ListView1.Items.Count) do
  begin
    lItem := ListView1.Items[i];

    if Pos(lTemp, AnsiUpperCase(lItem.SubItems.Text)) <> 0 then
    begin
      ListView1.HideSelection := False;
      ListView1.Selected := lItem;
      lItem.MakeVisible(False);
      Break;
    end;
  end;
end;
1. MakeVisible()
2. Schleife abbrechen, wenn Eintrag gefunden
3. Selected sollte schneller als ItemIndex sein.
4. AnsiUpperCase() nach Bernhard Geyer rausgezogen
5. nur einmaliger Zugriff auf Items[] Array Property

Dash 2. Jan 2007 21:07

Re: ListView - Suche sehr langsam
 
Danke, aber an der Geschwindigkeit hat sich leider nicht viel geändert :cry:
Delphi-Quellcode:
procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
  i: Integer;
  s: String;
begin
  s := ansiuppercase(LabeledEdit1.Text);
  for i := 0 to ListView1.Items.Count - 1 do
  begin
    if pos(s, ansiuppercase(ListView1.Items[i].SubItems.Text)) <> 0 then
    begin
      ListView1.HideSelection := False;
      ListView1.ItemIndex := i;
    end;
  end;
end;

Dash 2. Jan 2007 21:10

Re: ListView - Suche sehr langsam
 
Zitat:

Zitat von Muetze1
Delphi-Quellcode:
procedure TForm1.LabeledEdit1Change(Sender: TObject);
var
  i: Integer;
  lTemp: String;
  lItem: TListItem;
begin
  lTemp := AnsiUpperCase(LabeledEdit1.Text);

  for i := 0 to Pred(ListView1.Items.Count) do
  begin
    lItem := ListView1.Items[i];

    if Pos(lTemp, AnsiUpperCase(lItem.SubItems.Text)) <> 0 then
    begin
      ListView1.HideSelection := False;
      ListView1.Selected := lItem;
      lItem.MakeVisible(False);
      Break;
    end;
  end;
end;
1. MakeVisible()
2. Schleife abbrechen, wenn Eintrag gefunden
3. Selected sollte schneller als ItemIndex sein.
4. AnsiUpperCase() nach Bernhard Geyer rausgezogen
5. nur einmaliger Zugriff auf Items[] Array Property

Danke, ändert zwar nichts an der Geschwindigkeit aber jetzt wird wenigstens zum Eintrag hingescrollt :thumb:
Edit: Oh, hatte vergessen was vom Code zu übernehmen :oops:
Die Suche ist jetzt spürbar schneller!

Danke!!

Gruß
Dash

Luckie 3. Jan 2007 05:49

Re: ListView - Suche sehr langsam
 
Du hast einen Designfehler in deinem Programm. Trenne die Daten von der Oberfläche. Das heißt halte die Daten in einer entsprechenden Datenstruktur und benutze den Listview nur, um die Daten zu visualisieren. Alle Operationen auf den Daten werden auf der Datenstruktur durchgeführt. Willst du einen Eintrag im Listview markieren nach einer Suche, suchst in der Datenstruktur nach den Daten und wenn du sie dort gefunden hast, markierst du nur noch den korrspondierenden Eintrag im Listview.

Muetze1 3. Jan 2007 19:22

Re: ListView - Suche sehr langsam
 
Ich habe auch eine ListView in meinem Programm und halte aber die Daten in eigenen Strukturen. Dort kann ich aber nicht suchen, da die Ausgabe nunmal anders formatiert wird. Daher ist es einfach nur mit höherem Aufwand möglich, in den internen Listen zu suchen, da man immer aus den Daten erstmal die Strings generieren muss für die Ausgabe.

Gerade dass ist doch mit einer der Vorteile der Trennung GUI und Daten: Man hat die Daten und kann die Ausgabe sonstwie formatieren und ausgeben - oder willst du mir sagen, dass du die Daten auch entsprechend formatiert in deinen internen Listen bereithälst?

Es ist einfach nicht immer alles mit dieser Faustformel lösbar. Ich programmiere grundsätzlich so, könnte mit deinem Vorwurf des Designfehlers hier nichts anfangen ausser beleidigt zu sein. Schließlich hast du keine Ahnung wie das restliche Konzept aussieht von mir/ihm und ob es überhaupt mit dieser strikten Trennung in diesem Falle der Suche überhaupt lösbar wäre.

Ohne die näheren Umstände zu kennen ist der Vorwurf einfach nur aus der Luft gegriffen und frech.

Dash 5. Jan 2007 08:50

Re: ListView - Suche sehr langsam
 
Also Muetze seine Lösung war jetzt eigentlich perfekt.
Nur habe ich wieder ein neues Problem:

Bei über 10000 Einträgen gibt es natürlich mehrere Treffer bei der Suche. Wie blende ich jetzt am besten alle Einträge aus bis auf die, die mit der Suche übereinstimmen? Wenn das Suchfeld leer ist müssen natürlich sofort wieder alle Einträge da sein. Ich könnte mir vorstellen das es hier wieder Geschwindigkeitsprobleme geben könnte...

Gtuß
Dash

Bernhard Geyer 5. Jan 2007 09:09

Re: ListView - Suche sehr langsam
 
Dazu mußt du entweder den Ansatz von Luckie machen (GUI und Datenhaltung trennen sowie z.B. den Listview im Virtualmodus betreiben oder einen ListView-Control nehmen das einzelne Items ausblenden kann.

Dash 6. Jan 2007 14:30

Re: ListView - Suche sehr langsam
 
Also ich habe jetzt mal ein wenig rumprobiert, allerdings ist dabei nichts gescheites rausgekommen. Ich werde mal Ausschau nach einer neuen ListView halten. Mal sehen was die VirtualListView so kann.

Gruß
Dash


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz