Einzelnen Beitrag anzeigen

frieder2008

Registriert seit: 28. Feb 2009
78 Beiträge
 
#16

Re: IndexOf case sensitive / Performance verbessern

  Alt 8. Mär 2009, 11:43
Hi Satty67,

danke für die Funktion, hast nur den Count überstrapaziert (..-1),

Delphi-Quellcode:
function IndexOf_CS(aStrings: TStrings; aToken : String):Integer;
  var
    i : Integer;
  begin
    Result := -1;
    for i := 0 to aStrings.Count -1 do
      if aStrings[i]=aToken then begin
        Result := i;
        Break;
      end;
  end;
aber sonst läuft das sogar schneller! als das Stringlist.IndexOf

- Und genau dazu hätte ich auch nochmal eine grundlegende Frage: Das hier ist jetzt nicht das erste mal, dass ich eine selbstgebastelte Funktion habe, die schneller läuft wie eine von der VCL bereitgestellte Routine. Anders gesagt: Dann lohnt es sich offenbar, im Zweifelsfall sich die VCL-Routine zu nehmen und abzuspecken; spricht da was aus Profi-Sicht dagegen?

- Grundlegend ist die Frage deshalb für mich, weil ich nicht 170.000, sondern ~ 2.000.000 Vergleiche durchführen (bzw. Wörter in Texten analysieren) muss. Und da wirds bei entsprechender Größe (>1 Mio) derzeit noch viel zu langsam. Könnte mal unten jemand durchgucken, wo man evtl. durch Tricks oder alternative Routinen Zeit sparen könnte? DANKE!

- Schließlich: Hilft es, anstatt mit StringLists mit anderen Objekten zu arbeiten? Oder Prozess-Priorität für Prog erhöhen (Nachteile?)?

1) Jede Datei in Stringlist laden:
textinhalt.LoadFromFile(path + filelist.Items.Strings[i]) 2) Bestimmte Zeichen rauslöschen: " und ' wie hier:
Delphi-Quellcode:
  repeat
    i:= ansicharpos('"', s);
    if i<>0 then s[i]:= ' ';
  until i=0;
3) Geladenes File bzw. Stringlist.text in Tokens auflösen:
Delphi-Quellcode:
      Extractstrings([' ', '.', ',', ';', '?', ':', '-', '(', ')', '[', ']', '<', '>', '/', '\', '_', '*', '+', '=', '^', CHR(096),
       CHR(039), CHR(127), CHR(126), CHR(124), CHR(130), CHR(132), CHR(133), CHR(139), CHR(145)], ['.', ',', ';', '?', ':', '-',
       '(', ')', '[', ']', '<', '>', '/', '\', '_', '*', '+', '=', '^', CHR(096), CHR(039), CHR(127), CHR(126), CHR(124), CHR(130), CHR(132), CHR(133), CHR(139), CHR(145), CHR(146), CHR(147), CHR(148), CHR(151), CHR(155), CHR(171), CHR(180), CHR(187),
       CHR(146), CHR(147), CHR(148), CHR(151), CHR(155), CHR(171), CHR(180), CHR(187)], pchar(textinhalt.text), tokenlist);
EDIT: => Ich habe so im Gefühl, dass man hier noch was machen könnte, nur wie.. Mein Grundansatz wäre einfach, die Zeichen jeder Datei durch zu gehen und bei Leerzeichen eben zu einem Wort zusammenfügen und in die Liste ablegen. Aber das wird am Ende doch schlechter laufen als ExtractString, oder?

Eine Möglichkeit wäre auch - das würde viel Zeit sparen! -, wenn ich ExtractStrings dazu bekäme, " und ' (einfaches und doppelte Anführungszeichen) nicht mehr als besondere Separatoren zu interpretieren; dann müsste ich die vorherh nicht mehr rausfischen..

4) Tokens zählen
Delphi-Quellcode:
      for iii:=0 to tokenlist.Count -1 do
        begin
        if Form1.checkbox2.checked then occurindex := IndexOf_CS(tokenlistges, tokenlist[iii])
          else occurindex:= tokenlistges.indexof(tokenlist[iii]);
        if occurindex >=0 then tokenlistges.Objects[occurindex]:= TObject(Succ(Integer(tokenlistges.Objects[OccurIndex])))
          else tokenlistges.AddObject(tokenlist[iii],TObject(1));
        end;
      end;
5) Gesamtergebnisse in Listview ausgeben
Delphi-Quellcode:
 for ii := 0 to Tokenlistges.Count - 1 do
          with listenview do begin
            listitem := items.Add;
            listitem.Caption := Tokenlistges[ii];
            listitem.SubItems.Add(inttostr(integer(Tokenlistges.objects[ii])));
            end;
6) Aufräumen..

Gruß, frieder
  Mit Zitat antworten Zitat