Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam (https://www.delphipraxis.net/195839-eintrag-aus-stringgrid-mit-eintrag-aus-listview-vergleichen-sehr-langsam.html)

verkouter 30. Mär 2018 17:20


Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Hallo,
ich habe ein Stringgrid indem 2600 Bohrpunkte mit zugehörigen Koordinaten gespeichert sind und ich habe ein Listview in dem Dateinamen von Protokollen und als
1.Subitem der Bohrpunkt gespeichert ist.
Ich vergleiche jetzt per Schleife jede Stringgridreihe mit allen Listviewreihen, ob es einen Listvieweintrag mit gleichem Bohrpunkt gibt.Das sind also 2600 mal 2600
Vergleiche, das ist natürlich extrem langsam. Hat jemand eine andere Idee.

Delphi-Quellcode:
function FindListViewItem(lv: TListView; const S: string; column: Integer): TListItem;
var
i: Integer;
found: Boolean;
begin
Assert(Assigned(lv));
Assert((lv.viewstyle = vsReport) or (column = 0));
Assert(S <> '');
for i := 0 to lv.Items.Count - 1 do
begin
Result := lv.Items[i];
if column = 0 then
found := AnsiCompareText(Result.Caption, S) = 0
else if column > 0 then
found := AnsiCompareText(Result.SubItems[column - 1], S) = 0
else
found := False;
if found then
Exit;
end;
Result := nil;
end;

procedure TForm1.ToolButton23Click(Sender: TObject);
var
lvItem: TListItem;
begin
for I := stringgrid2.RowCount-1 downto 1 do
begin
lvItem := FindListViewItem(ListView1, stringgrid2.Cells[0,i], 1);
if lvItem <> nil then
begin
{mach was}
end;
end;
end;

günni0 30. Mär 2018 17:37

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Als erstes natürlich alle Daten in nicht sichtbaren Strukturen speichern. Hier bietet sich doch eine generische TList an, Records oder Klassenstrukturen.
Aber Daten in den visuellen Komponenten speichern ist eigentlich immer Pfui.

haentschman 31. Mär 2018 05:45

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Moin...:P
Zitat:

Aber Daten in den visuellen Komponenten speichern ist eigentlich immer Pfui.
+1 :thumb:

KodeZwerg 31. Mär 2018 07:36

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Falls es funktioniert, setze ein BeginUpdate in der FindListView() (oder sogar schon in der ToolButton23Click()) Funktion relativ weit oben und kurz vor Schluss ein EndUpdate. Das sollte theoretisch alles um 100% beschleunigen.
Zitat:

Zitat von günni0 (Beitrag 1397678)
Aber Daten in den visuellen Komponenten speichern ist eigentlich immer Pfui.

Na wie bekommst Du denn Daten in ein Stringgrid ohne sie zu laden?

[Edit]
Was mir gerade noch so Einfällt um alles enorm zu beschleunigen, an der Stelle wo Du Dein Stringgrid mit Daten füllst, bastel eine kleine Unterfunktion ein die folgendes macht:
Bohrpunkte in Stringgrid-Column[XY] rein PLUS Bohrpunkte in ein Array, im Nachhinein nurnoch das Array nach Werten durchforsten. Eine TList geht auch, sollte die gleiche Performance bringen.
[/Edit]

DeddyH 31. Mär 2018 09:12

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Erst lesen, dann verstehen, dann erst posten (oder auch nicht), das ist der ideale Weg. Es ging nicht um die Darstellung und damit das Laden der Daten, sondern darum, wo sie vorgehalten werden. Und da sind visuelle Komponenten die schlechteste Alternative.

Daniel 31. Mär 2018 10:52

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von KodeZwerg (Beitrag 1397728)
Falls es funktioniert, setze ein BeginUpdate in der FindListView() (oder sogar schon in der ToolButton23Click()) Funktion relativ weit oben und kurz vor Schluss ein EndUpdate. Das sollte theoretisch alles um 100% beschleunigen.

Nein, tut es nicht. Nicht mal um 1%. Die obige Funktion liest den ListView aus, verändert ihn nicht. Der Aufruf von .BeginUpdate und .EndUpdate wirkt sich hier nicht aus.

@verkouter: Hast Du Einfluss auf die Reihenfolge Deiner Rohdaten? Angenommen, sie lägen sortiert vor, könntest Du Dir viele Vergleiche sparen, weil z.B. ab einem gewissen Punkt nur noch größere Elemente kommen können als das gesuchte. (Nur als Beispiel...)
Alternativ: Wie oft baust Du Grid und ListView auf und wie oft suchst Du? Man könnte beim Aufbau der Controls eine Art Lookup schaffen. Hier gäbe es beispielsweise das Dictionary, mit dem Du eine Abbildung von Bohrloch-Daten zu StringGrid-Zeilen machen könntest, sei es 1:1 oder 1:n.

KodeZwerg 31. Mär 2018 11:38

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Darf ich mal etwas Fragen was glaube ich zum Thema passt und helfen würde es besser zu Verstehen .... (das hat nichts mit dem Thema "suchen/vergleichen" am Hut sondern Perfomance bzw Logik)

Also man hat eine Datei, möchte sich aus der Datei Daten in ein Stringgrid Anzeigen lassen, nun füll ich das Stringgrid mit Daten weil sie ja visuell Dargestellt werden sollen.
Wenn ich nun die Daten vorher in eine TList oder Array oder sonst was lade/puffer um sie dann trotzdem visuell darzustellen, in wie fern beschleunigt es die visuelle Komponente wenn die Daten aus einem TList o.ä. kommen anstelle direkt von der Datei?

Mit dem Begin/EndUpdate hatte ich angemerkt "Falls es funktioniert" weil ich mir nicht sicher war, danke für Klarstellung.

Der zweite Tipp von mir allerdings sollte definitiv funktionieren da ich es selbst so einsetze, wobei anzumerken ist das ich bei mir mein Array und die Visuelle Komponente so abgestimmt habe das beide immer den gleichen Index besitzen was mir beim suchen und anzeigen einen enormen Performance Vorteil einbringt. (suchen in einem Array mit 500.000 Einträgen = wenn es langsam ist (CPU/Core auslastung hoch) dauerts zwei bis drei Sekunden aber in der Regel ist ein Ergebniss unter einer Sekunde da)

günni0 31. Mär 2018 11:47

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

in wie fern beschleunigt es die visuelle Komponente wenn die Daten aus einem TList o.ä. kommen anstelle direkt von der Datei?
Meiner Meinung nach gibt es da keinen nennenswerten Unterschied wenn man mal von den Lesevorgängen von der Festplatte absieht.

Von einer Liste zu laden hat aber den unschlagbaren Vorteil, dass man immer alle Daten parat und schon in einer passenden Datenstruktur hat und nicht immer wieder von der Festplatte lesen und aufbereiten muss.
Auf Dauer könnte es also schneller sein, nicht aber bei einmaliger Anwendung.

KodeZwerg 31. Mär 2018 12:22

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Ah Okay, das Verstehe sogar ich :thumb:
Klingt ja auch logisch im Nachhinein :oops:

EWeiss 31. Mär 2018 13:23

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Meiner Meinung nach gibt es da keinen nennenswerten Unterschied wenn man mal von den Lesevorgängen von der Festplatte absieht.
Dann nenne ich dir einen.
Es könnten unnötige Messagen aufgerufen werden wenn ich Daten direkt aus einer Visuellen Komponente abrufe.
Zum Beispiel WM_PAINT ob das erwünscht und tragbar ist mag dahin gestellt sein.

Und ja wenn es so ist macht es sehr wohl einen großen Unterschied.

gruss

Olli73 31. Mär 2018 13:48

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von KodeZwerg (Beitrag 1397735)
Also man hat eine Datei, möchte sich aus der Datei Daten in ein Stringgrid Anzeigen lassen, nun füll ich das Stringgrid mit Daten weil sie ja visuell Dargestellt werden sollen.
Wenn ich nun die Daten vorher in eine TList oder Array oder sonst was lade/puffer um sie dann trotzdem visuell darzustellen, in wie fern beschleunigt es die visuelle Komponente wenn die Daten aus einem TList o.ä. kommen anstelle direkt von der Datei?

Du kannst den Inhalt des StringGrid auch selber zeichnen (onDrawCell), dann sparst du dir das Kopieren/Speichern im StringGrid.

günni0 31. Mär 2018 14:25

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von EWeiss (Beitrag 1397744)
Zitat:

Meiner Meinung nach gibt es da keinen nennenswerten Unterschied wenn man mal von den Lesevorgängen von der Festplatte absieht.
Dann nenne ich dir einen.
Es könnten unnötige Messagen aufgerufen werden wenn ich Daten direkt aus einer Visuellen Komponente abrufe.
Zum Beispiel WM_PAINT ob das erwünscht und tragbar ist mag dahin gestellt sein.

Und ja wenn es so ist macht es sehr wohl einen großen Unterschied.

gruss

Ob WM_PAINT oder nicht ist völlig egal. Denn beim Befüllen der visuellen Komponente aus der Listenstruktur wird es ohnehin aufgerufen.
Also zählt WM_PAINT nicht.

verkouter 31. Mär 2018 16:31

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Die Daten in dem Stringgrid sind der Größe nach sortiert (Bohrpunkte).
Die Listview enthält mehrere Subitems mit Datum usw. und werden vom Anwender umsortiert.

Delphi.Narium 31. Mär 2018 17:29

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Ist das richtig, Du nutzt Delphi 6?
Bei Delphi 7 verfügt TListView über die Methoden FindCaption und FindData. Gab es die bei Delphi 6 noch nicht?

Wenn es sie bereits geben sollte, könnten sie eventuell eine Alternative für die Suche sein, statt über alle Einträge zu iterieren.

Zitat:

Zitat von Delphi 7 - Hilfe
FindCaption (Methode von TCustomListView)

Die Methode FindCaption gibt einen Listeneintrag mit dem angegebenen Titel zurück.

Delphi-Syntax:

function FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;

C++ Syntax:

TListItem* __fastcall FindCaption(int StartIndex, AnsiString Value, bool Partial, bool Inclusive, bool Wrap);

Beschreibung

Mit FindCaption können Sie nach dem Eintrag in der Liste suchen, dessen Titel mit dem String im Parameter Value identisch ist. Wenn der Parameter Inclusive den Wert true hat, wird die Überprüfung bei dem in StartIndex angegebenen Listeneintrag begonnen. Andernfalls beginnt die Suche beim nächsten Element. Ist der Parameter Wrap true, wird die Suche am Anfang der Liste fortgesetzt, wenn der gesuchte Eintrag bis zum Listenende nicht gefunden wurde. FindCaption gibt den ersten Eintrag zurück, dessen Eigenschaft Caption mit Value identisch ist. Wenn der Parameter Partial auf true gesetzt wird, werden auch Titel gefunden, die mit dem Teilstring Value beginnen. Hat Partial den Wert false, wird nach einer genauen Übereinstimmung gesucht. Wenn kein Eintrag gefunden wird, gibt FindCaption nil (Delphi) bzw. NULL (C++) zurück.

Eine ganz blöde Idee:

Manchmal kann es die Arbeit mit visuellen Komponenten deutlich beschleunigen, wenn man das Programm solange minimiert.

Delphi-Quellcode:
procedure TForm1.ToolButton23Click(Sender: TObject);
var
  lvItem: TListItem;
begin
  Application.Minimize;
  for I := stringgrid2.RowCount-1 downto 1 do
  begin
    lvItem := FindListViewItem(ListView1, stringgrid2.Cells[0,i], 1);
    if lvItem <> nil then
    begin
     {mach was}
    end;
  end;
  Application.Restore;
end;
Und nein, elegant ist das nicht. :oops:

p80286 31. Mär 2018 17:46

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von günni0 (Beitrag 1397678)
Als erstes natürlich alle Daten in nicht sichtbaren Strukturen speichern. Hier bietet sich doch eine generische TList an, Records oder Klassenstrukturen.
Aber Daten in den visuellen Komponenten speichern ist eigentlich immer Pfui.

Performance und visuelle Komponenten schließen sich gegenseitig aus. Man mag darüber diskutieren ob eine Tlist oder eine TStringlist hier besser ist, solange es keine visuelle Komponente ist, ist es auf jeden Fall schneller. Und es geht hier nicht um 10% sondern um 50..80%.

Gruß
K-H

dummzeuch 31. Mär 2018 18:01

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von KodeZwerg (Beitrag 1397735)
Also man hat eine Datei, möchte sich aus der Datei Daten in ein Stringgrid Anzeigen lassen, nun füll ich das Stringgrid mit Daten weil sie ja visuell Dargestellt werden sollen.
Wenn ich nun die Daten vorher in eine TList oder Array oder sonst was lade/puffer um sie dann trotzdem visuell darzustellen, in wie fern beschleunigt es die visuelle Komponente wenn die Daten aus einem TList o.ä. kommen anstelle direkt von der Datei?

Für sowas bieten sich virtuelle aka owner drawn controls an. Z.B. mein dzVirtualStringGrid (oder man programmiert es halt selbst, ist kein großer Akt). Dann lädt man die Daten nur noch in den Speicher und zeigt sie per Events an.

EWeiss 31. Mär 2018 18:08

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Zitat von p80286 (Beitrag 1397764)
Zitat:

Zitat von günni0 (Beitrag 1397678)
Als erstes natürlich alle Daten in nicht sichtbaren Strukturen speichern. Hier bietet sich doch eine generische TList an, Records oder Klassenstrukturen.
Aber Daten in den visuellen Komponenten speichern ist eigentlich immer Pfui.

Performance und visuelle Komponenten schließen sich gegenseitig aus. Man mag darüber diskutieren ob eine Tlist oder eine TStringlist hier besser ist, solange es keine visuelle Komponente ist, ist es auf jeden Fall schneller. Und es geht hier nicht um 10% sondern um 50..80%.

Gruß
K-H

Ach lass ihn doch bei seinem glauben manche wissen es halt besser.

gruss

günni0 31. Mär 2018 18:35

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Ach lass ihn doch bei seinem glauben manche wissen es halt besser.
Muss man deinen Beitrag verstehen?

Was hab ich denn so schlimmes gesagt, worauf p80286 geantwortet hat? Ich sagte nur, man sollte seine Daten nicht direkt in visuellen Komponenten speichern.
Wer es trotzdem macht und das auch noch gut findet, sollte ernsthaft überlegen was er da tut.

Rumstänkern und Beiträge nur halb lesen ist jedenfalls keine Lösung.

Ließ dir meinen und p80286s Beitrag noch einmal ganz in Ruhe durch!

EWeiss 31. Mär 2018 18:37

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Zitat:

Was hab ich denn so schlimmes gesagt, worauf p80286 geantwortet hat? Ich sagte nur, man sollte seine Daten nicht direkt in visuellen Komponenten speichern.
Wer es trotzdem macht und das auch noch gut findet, sollte ernsthaft überlegen was er da tut.
Ich habe nichts anderes gesagt. ;)

Deine Antwort drauf.
Zitat:

Ob WM_PAINT oder nicht ist völlig egal. Denn beim Befüllen der visuellen Komponente aus der Listenstruktur wird es ohnehin aufgerufen.
Widersprichst du dir da nicht selbst.?
Oder aber du hast meinen Beitrag dazu falsch verstanden. Wie dem auch sei.

Zitat:

Rumstänkern und Beiträge nur halb lesen ist jedenfalls keine Lösung.
Habe auch keinen Bock auf Gezanke..

gruss

KodeZwerg 1. Apr 2018 17:40

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Das WM_PAINT oder andere visuelle Komponente gedönse schalte ich zumindest mit Begin/EndUpdate vorübergehend aus, ob ein minimieren den gleichen Effekt erzielt habe ich so noch nie getestet, zumindest falls es klappt ist es eine weitere Methode ala Begin/EndUpdate effekt ODER ganz krass: dann sollte ja auch ein "Hide" der Komponente diesen Effekt hervor rufen, so hat man zumindest noch ein Fenster sichtbar :D

Delphi.Narium 1. Apr 2018 17:51

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Wichtig ist eigentlich nur, dass die Komponenten nicht sichtbar sind. Das "ewige" Neuzeichnen frist die meiste Rechenzeit.

Ob man das Programm nun minimiert oder Hide aufruft, ist gehupft wie gesprungen. In beiden Fällen ist's unsichtbar und damit entfällt die "Malerei".

verkouter 1. Apr 2018 19:50

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Habe Stringgrid und Listview unsichtbar gemacht, kein Geschwindigkeitsvorteil.

KodeZwerg 1. Apr 2018 20:03

AW: Eintrag aus Stringgrid mit Eintrag aus Listview vergleichen sehr langsam
 
Wenn Du magst, bereite ich Dir Deinen Source mit meinem Array Tipp vor, oder Versuche selbst was die anderen schrieben.
Das mit dem Lookup hörte sich auch interessant an.
Falls ich's vorbereiten soll, brauch ich komplett Projekt-Source + Testdatei mit Bohrungen, der Source kann von mir aus abgespeckt auf das was du erreichen willst sein (Stringgrid, Bohr-Datei reinladen, neuen Eintrag erstellen).


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:51 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