Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi RichEdit.FindText beschleunigen (https://www.delphipraxis.net/107652-richedit-findtext-beschleunigen.html)

Franzelchen 31. Jan 2008 08:54


RichEdit.FindText beschleunigen
 
Hallo!

Ich habe ein Problem mit RichEdit.FindText

Ich färbe Elemente einer Listbox in einem RichEdit rot ein. Zum Suchen dieser Elemente benutze ich FindText. Das dauert relativ lange auf meinem 400 Mhz Rechner. Nun meine Frage: Gibt es eine Möglichkeit FindText zu beschleunigen? Beispiel FastStrings für schnelle Stringoperationen.

taaktaak 31. Jan 2008 09:00

Re: RichEdit.FindText beschleunigen
 
Moin, Moin.

Zitat:

färbe Elemente einer Listbox in einem RichEdit
Das verstehe ich nicht - Listbox? Richedit? Gibt's nach D7 ein anderes Richtedit mit integrierter ListBox?

Gruß Ralph

Bernhard Geyer 31. Jan 2008 09:00

Re: RichEdit.FindText beschleunigen
 
- Neuerer Rechner ( :mrgreen: )
- Andere Komponente (TRichView)
- FastStrings selbst ausprobieren

marabu 31. Jan 2008 09:01

Re: RichEdit.FindText beschleunigen
 
Hallo,

wie groß ist der Text im RichEdit und wieviele Einträge hat die ListBox mit den Suchworten?
Zeige mal deinen Code. Vermutlich greifst du des öfteren auf die Eigenschaft RichEdit.Lines.Text zu.

Grüße vom marabu

Franzelchen 31. Jan 2008 09:13

Re: RichEdit.FindText beschleunigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Anbei mein Quelltext.

marabu 31. Jan 2008 09:36

Re: RichEdit.FindText beschleunigen
 
Der Zugriff auf RichEdit.Text innerhalb der Schleife ist eine gewaltige Bremse.

Hier noch ein Link zum gleichen Thema: klick

Freundliche Grüße

Franzelchen 31. Jan 2008 10:05

Re: RichEdit.FindText beschleunigen
 
Besten Dank! Ich probiere es gleich mal aus.

Franzelchen 1. Feb 2008 12:11

Re: RichEdit.FindText beschleunigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab's ausprobiert.

Statt schneller zu werden liefert FindTextAll Fehler über Fehler.

Anbei der eingebaute Quelltext vom Marabu

marabu 1. Feb 2008 13:15

Re: RichEdit.FindText beschleunigen
 
Hallo,

ich habe mir dein Test-Projekt kurz angeschaut und folgendes festgestellt:

(1) Fehler treten bei mir nicht auf.
(2) Wenn ich auf den Button "Marabu" klicke, dann vergehen 19 Sekunden bis 483 Treffer markiert wurden.
(3) Wenn ich auf den Button "Meine" klicke, dann werden in 0.5 Sekunden 410 Treffer markiert.

Daraus schließe ich zuerst einmal, dass die beiden Codes nicht das Gleiche tun. Ich werde das heute abend genauer analysieren.

Freundliche Grüße

Franzelchen 1. Feb 2008 13:54

Re: RichEdit.FindText beschleunigen
 
Hallo Marabu,

Fehler treten nicht auf???

marabu 1. Feb 2008 19:38

Re: RichEdit.FindText beschleunigen
 
Nein, Laufzeit-Fehler treten bei mir nicht auf.

Ich habe mir den Code jetzt genauer angesehen. Die von mir verlinkte Funktion FindTextAll() enthält genau die Bremse, vor der ich dich warnen wollte. Hier die korrigierte Fassung:

Delphi-Quellcode:
function FindTextAll(re: TRichEdit; const sText: string;
    options: TSearchTypes): TIntegerDynArray;
var
  iStart, iFound, iLength: Integer;
begin
  SetLength(Result, 0);
  iStart := 0;
  iLength := Length(re.Text); // re.Lines.Text war fatal
  while iStart < (iLength - Length(sText)) do
  begin
    iFound := re.FindText(sText, iStart, iLength - iStart, options);
    if iFound = -1 then Break;
    SetLength(Result, Succ(Length(Result)));
    Result[High(Result)] := iFound;
    iStart := iFound + Length(sText);
  end;
end;
Den Geschwindigkeitsvorteil ziehst du in deinem Code aus zwei fiesen Tricks: Du suchst immer nur nach dem ersten Treffer, weitere ignorierst du, und du verkleinerst den Suchbereich mit jedem Treffer. Wird ein Suchwort am Ende des Textes gefunden, dann beginnst du mit der Suche nach dem nächsten Suchwort direkt hinter dem vorigen Treffer. Dein Text enthält 34.630 Zeichen, insgesamt durchsucht werden bei dir 35.037 Zeichen. Bei etwa gleichmäßig im Text verteilten Suchwörtern müsstest du aber pro einfachem Treffer etwa 17.315 Zeichen untersuchen, bei 410 Durchläufen sind das etwa 7MB. Mein Code findet übrigens 483 Treffer.

Der Vergleich der beiden Lösungen hinkt ein wenig, meinst du nicht auch?

Franzelchen 2. Feb 2008 12:48

Re: RichEdit.FindText beschleunigen
 
Hallo Marabu!

Zitat:

Zitat von marabu

Du suchst immer nur nach dem ersten Treffer, weitere ignorierst du, und du verkleinerst den Suchbereich mit jedem Treffer. Wird ein Suchwort am Ende des Textes gefunden, dann beginnst du mit der Suche nach dem nächsten Suchwort direkt hinter dem vorigen Treffer.


Und genau so ist es ja auch gemeint.

Diese Prozedur ist trotz des beschriebenen Geschwindigkeitsvorteils für meinen Rechner der langsamste Teil im Gesamtprogramms. Deswegen frage ich ja nach einer Beschleunigungsmöglichkeit von RE.FindText .

Ich probiere mal Deinen Source aus und bedanke mich für deine bisherige Hilfe.

marabu 2. Feb 2008 14:13

Re: RichEdit.FindText beschleunigen
 
Hallo,

dass du nur die jeweils erste Fundstelle markieren willst, ist für mich unverständlich. Die sukzessive Einschränkung des Suchbereiches wird in der Informatik nur bei der Feststellung einer bestimmten Ordnung angewandt - diese Aufgabenstellung geht aber weder aus deiner Beschreibung noch aus den Daten hervor, aberseisdrum ...

Eine drastische Beschleunigung der Textsuche könntest du durch den Einsatz eines Directed Acyclic Word Graph (Hier im Forum suchenDAWG) erreichen. Dabei werden die Buchstaben der Suchbegriffe in einen Baum eingetragen und jedes Suchwort entspricht einem Pfad im Baum. Deine Suche geschieht dann eigentlich anders herum: Du prüfst deinen zu durchsuchenden Text anhand des Baums auf existierende Pfade.

Es gibt noch andere Ansätze für eine beschleunigte Suche, die alle effizienter sind als die Methode FindText, aber der DAWG ist leicht zu implementieren und hat einen sehr großen Kosten-Nutzen-Effekt.

Freundliche Grüße

Franzelchen 16. Feb 2008 12:35

Re: RichEdit.FindText beschleunigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!

Zitat:

Zitat von marabu
Hallo,

Eine drastische Beschleunigung der Textsuche könntest du durch den Einsatz eines Directed Acyclic Word Graph (Hier im Forum suchenDAWG) erreichen. Dabei werden die Buchstaben der Suchbegriffe in einen Baum eingetragen und jedes Suchwort entspricht einem Pfad im Baum. Deine Suche geschieht dann eigentlich anders herum: Du prüfst deinen zu durchsuchenden Text anhand des Baums auf existierende Pfade.

Es gibt noch andere Ansätze für eine beschleunigte Suche, die alle effizienter sind als die Methode FindText, aber der DAWG ist leicht zu implementieren und hat einen sehr großen Kosten-Nutzen-Effekt.

Freundliche Grüße

Die Implementation fällt mir nicht ganz so einfach wie Marabu es schreibt.
Ich habe den RE.Text in ein Dawg geschrieben. Das geht sehr leicht.
Das Durchsuchen des RE.dawg mit den Einträgen der Listbox fällt mir schon wesentlich schwerer.
Es erscheinen Variant Fehler. In der Schleife die ich eingefügt habe um die Listbox abzuarbeiten sind offensichtlich auch noch Fehler.
An das Hauptproblem : die Markierung der Listbox Einträge im Dawg , traue ich mich gar nicht erst heran.

Hilfe!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:02 Uhr.

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