Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Suche effizienter machen (https://www.delphipraxis.net/120958-suche-effizienter-machen.html)

Zioone 19. Sep 2008 13:11


Suche effizienter machen
 
Hallo,
mein Programm soll für voreingestellte Schlüsselwörter, wenn etwas gesucht oder die Datei geöffnet wurde, farbig hervorheben.

Das funktioniert auch.
Mein Problem ist nur, wenn ich sehr große Dateien habe ala Zeilen >2000, dann dauert das eine halbe Ewigkeit.

Ich wollte nur mal wissen ob wer eine Idee hat, dieses Suchen/markieren effizienter zu machen oder ob ich mit der Geschwindigkeit leben muss.
Hier der Code:
Delphi-Quellcode:
i2:=0;

    for ii := 0 to FSelectCount-1 do
    begin
      if FSelect.Strings[ii] <>'' then
      begin
        if (text<>'') OR (text2<>'') OR (text3<>'') then
        begin
          if (Pos( LowerCase(text), LowerCase( FSelect.Strings[ii] ) )) > 0 then
          begin
            i:=Pos( LowerCase(text), LowerCase( FSelect.Strings[ii] ) );
            mmoLines.SelStart := i+i2-1;
            mmoLines.SelLength := Length(text);
            mmoLines.SelAttributes.Color := c;
            mmoLInes.SelAttributes.Style := [fsBold];
            mmoLines.SelLength := 0;
          end;
          if Pos( LowerCase(text2), LowerCase( FSelect.Strings[ii] ) ) > 0 then
          begin
            i:=Pos( LowerCase(text2), LowerCase( FSelect.Strings[ii] ) );
            mmoLines.SelStart := i+i2-1;
            mmoLines.SelLength := Length(text2);
            mmoLines.SelAttributes.Color := c2;
            mmoLInes.SelAttributes.Style := [fsBold];
            mmoLines.SelLength := 0;
          end;
          if Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) ) > 0 then
          begin
            i:=Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) );
            mmoLines.SelStart := i+i2-1;
            mmoLines.SelLength := Length(text3);
            mmoLines.SelAttributes.Color := c3;
            mmoLInes.SelAttributes.Style := [fsBold];
            mmoLines.SelLength := 0;
          end;
        end;
      end;
        i2 := i2+Length(FSelect.Strings[ii])+2;
    end;
wobei FSelect eine Stringlist ist
und text und color und c aus einer ini datei gelesen werden

über Ideen wäre ich dankbar :)

taaktaak 19. Sep 2008 13:29

Re: Suche effektiver machen
 
Moin, Moin,
Spontan drei Bemerkungen dazu:
1) Das ständige "LowerCase(FSelect.Strings[ii])" kostet Zeit und würde überflüssig, wenn es 1x VOR der Schleife erledigt wird.
2) Prüfe, ob die Suche nach einem Schlüsselwort in der Stringlliste mit IndexOf() schneller ist als mit Pos()
3) Wenn dein Code seinen Zweck erfüllt, ist er bereits effektiv! Wenn er seinen Zweck erfüllen und besonders schnell sein soll, dann ist er effizient!

nahpets 19. Sep 2008 13:35

Re: Suche effektiver machen
 
Hallo,

mal so ein bisserl schmutzig von mir dahingeschrieben:

Delphi-Quellcode:
if (text<>'') OR (text2<>'') OR (text3<>'') then
Mach Dir dafür 'nen boolschen Schalter, dann musst Du nur einmal abfragen

Delphi-Quellcode:
b := (text<>'') OR (text2<>'') OR (text3<>'');
Das kannst Du schon vor Deiner For-Schleife machen, ist b = false, kannst Du Dir die For-Schleife direkt sparen.

Text... werden bei jeder Abfrage mit Lowercase behandelt, mache das einmal vor der Schleife.
Delphi-Quellcode:
if Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) ) > 0 then
begin
  i:=Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) );
Prüfe bitte, ob Du vorab auch FSelect.Strings[ii] in Lowercase wandeln kannst, dann mach das vorab in einer separaten Schleife.

Die Position wird hier zweimal ermittelt, eventuell machst Du das besser so:
Delphi-Quellcode:
i := Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) );
if i > 0 then
begin
@taaktaak, IndexOf ist hier nicht geeignet, da nicht nach Strings in der Liste gesucht wird, sondern nach Teilstrings in den einzelnen Listeneinträgen, das kann IndexOf meines Wissens nicht.

Stephan

PS: taaktaak war schneller als ich :x

DerDan 19. Sep 2008 13:38

Re: Suche effektiver machen
 
Hallo,


wenn du die Einfärbung nur brauchst um sie auf dem Bildschirm darzustellen dann ist es effizienter wenn du nur die Zeilen bearbeitest, die momentan sichtbar sind.

Dafür gibt es mit der SynEdit auch schon fertige Komponenten.


mfg DerDan

Zioone 19. Sep 2008 13:55

Re: Suche effizienter machen
 
danke schon mal für die Antworten :thumb:

Nur was ich nicht ganz verstehe ist das ich das LowerCase vor der Schleife machen soll.
Sann kennt er doch gar nicht "ii"?!
und wenn ich das wieder in einer Schleife mache, hab ich ja auch nichts mit gewonnen o_O

Sorry, bin Anfänger ^^'

taaktaak 19. Sep 2008 14:00

Re: Suche effizienter machen
 
Mir ist nicht klar, wie du die Schlüsselwörter bereitstellst.
Lege eine Stringlist an, in der jedes Schlüsselwort ein Listenelement ist und dort als LowerCase abgelegt ist. Dann kannst du auch mit IndexOf() arbeiten.

Zioone 19. Sep 2008 14:04

Re: Suche effizienter machen
 
Die Schlüsselwörter speicher ich vorher in eine IniDatei
und lese sie dann an der Stelle wieder aus
Delphi-Quellcode:
ini :=TIniFile.Create(ExtractFilePath(ParamStr(0))+'settings.ini');
 
    text := ini.ReadString('settings','text1','Error');
    color := ini.ReadString('settings','color1','clred');
    if color<>'' then
    begin
      c:=StringToColor(color);
    end;
jetzt nur mal für den ersten text

nahpets 19. Sep 2008 14:08

Re: Suche effizienter machen
 
Hallo,
Zitat:

Zitat von Zioone
danke schon mal für die Antworten :thumb:

Nur was ich nicht ganz verstehe ist das ich das LowerCase vor der Schleife machen soll.
Sann kennt er doch gar nicht "ii"?!
und wenn ich das wieder in einer Schleife mache, hab ich ja auch nichts mit gewonnen o_O

Sorry, bin Anfänger ^^'

Ich versuchs mal:

Für jeden Eintrag in FSelect.Strings werden text, text2 und text3 in Lowercase gesetzt. Das kannst Du vor der Schleife machen, diese Werte sind unabhängig vom Inhalt der Strings.

Wenn Du ohne Probleme FSelect.Strings in Kleinbuchstaben umwandeln kannst, weil es ausserhalb der Schleife z. B. nicht gebraucht wird, dann mach' eine zweite Schleife vor die jetzige Schleife.

Delphi-Quellcode:
for ii := 0 to FSelect.count - 1 ) do FSelect.Strings[ii] := lowercase(FSelect.Strings[ii]);
dann wird aus
Delphi-Quellcode:
if Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) ) > 0 then
begin
  i:=Pos( LowerCase(text3), LowerCase( FSelect.Strings[ii] ) );
Delphi-Quellcode:
if Pos(text3,FSelect.Strings[ii]) > 0 then
begin
  i:=Pos(text3,FSelect.Strings[ii]);
und wenn Du das dann noch vertauschst, wird daraus
Delphi-Quellcode:
i:=Pos(text3,FSelect.Strings[ii]);
if i > 0 then
begin
Dadurch sparst Du Dir sehr viele Lowercase und sehr viele Pos.

Stephan

Zioone 19. Sep 2008 14:21

Re: Suche effizienter machen
 
ah, ok jetzt hab ich das verstanden.
Danke

Nur ob ich die Strings[ii] in einer seperaten schleife klein mache oder in der "richtigen" ist doch eigentlich egal?! :gruebel:

Und wie könnt ich jetzt mal am besten testen (in Zeitwerten) wie effizienter das ganze geworden ist?
So rein nach Gefühl ist das denke schon bisschen schneller, aber würde mich mal interessieren wie viel das nun genau gebracht hat.
Muss ich dafür jetzt testweise kompletten Timer programmieren?

nahpets 19. Sep 2008 14:43

Re: Suche effizienter machen
 
Hallo,
Zitat:

Zitat von Zioone
ah, ok jetzt hab ich das verstanden.
Danke

Nur ob ich die Strings[ii] in einer seperaten schleife klein mache oder in der "richtigen" ist doch eigentlich egal?! :gruebel:

Und wie könnt ich jetzt mal am besten testen (in Zeitwerten) wie effizienter das ganze geworden ist?
So rein nach Gefühl ist das denke schon bisschen schneller, aber würde mich mal interessieren wie viel das nun genau gebracht hat.
Muss ich dafür jetzt testweise kompletten Timer programmieren?

Nein, in der separaten Schleife machst Du alles nur einmal kein, in der großen Schleife jedes mal, für Text, für text2 und text3.

Wenn die Liste also 1000 Einträge enthält, wird jeder Eintrag der Stringliste 1 mal kleingemacht.
In Deiner Variante wird jeder Eintrag der Stringliste 1000 mal drei mal kleingemacht. Das läppert sich zusammen, auch wenn einmal kleinmachen allein gaaaanz schnell geht :wink:

Was das bringt: Nimm Deine "alte" Fassung mit einer definierten Liste und definiertem Text und schau auf die Uhr, wielange das dauert. Dann überarbeitest Du das Programm und machst den gleichen Test nochmal.

Die Uhr kannst Du Dir mit Delphi "selber bauen".

Vorher:
Delphi-Quellcode:
ShowMessage(DateTimeToStr(Now));
Uhrzeit aufschreiben
Nachher:
Delphi-Quellcode:
ShowMessage(DateTimeToStr(Now));
Uhrzeit aufschreiben und Zeitdifferenz ausrechnen.

Stephan


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:20 Uhr.
Seite 1 von 4  1 23     Letzte »    

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