Delphi-PRAXiS
Seite 5 von 5   « Erste     345   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   TStringlist mit 60000 Einträgen zu langsam (https://www.delphipraxis.net/147517-tstringlist-mit-60000-eintraegen-zu-langsam.html)

friedemann2009 12. Feb 2010 13:37

Re: TStringlist mit 60000 Einträgen zu langsam
 
Zitat:

Zitat von David Martens
Die Sortierung ist, glaube ich, schon wichtig. Mit .sorted := true; geht die verloren.

So isses.

himitsu 12. Feb 2010 14:03

Re: TStringlist mit 60000 Einträgen zu langsam
 
Zitat:

Zitat von friedemann2009
Zitat:

Zitat von David Martens
Die Sortierung ist, glaube ich, schon wichtig. Mit .sorted := true; geht die verloren.

So isses.

abgesehn davon suchst du auch nicht in den StringListen (nur in den einzelnen Teil-Strings), sondern greifst direkt via Index zu, wofür ein Sortierung keine Verbesserung bringt.


Ich hab jetzt einfach mal als Beispiel deinen Code aus Beitrag #15 genommem.
vor alles kommt jetzt der Teil davon:
Delphi-Quellcode:
var XXX: Array[0..40] of Int64;

procedure XStart(i: Integer);
var X: Int64;
begin
  QueryPerformanceCounter(X);
  XXX[i] := XXX[i] - X;
end;

procedure XStop(i: Integer);
var X: Int64;
begin
  QueryPerformanceCounter(X);
  XXX[i] := XXX[i] + X;
end;

procedure XShow;
var X: Int64;
  i: Integer;
  S: String;
begin
  S := '';
  QueryPerformanceFrequency(X);
  for i := 0 to High(XXX) do
    if (XXX[i] > 0) and (XXX[i] < $40000000000000 div x) then
      S := Format('%s %d:%dms', [S, i, (XXX[i] * 1000 + 500) div X])
    else if XXX[i] <> 0 then
      S := Format('%s %d:error', [S, i]);
end;
Und dann wird einfach für jeden "interessanten" Abschnitt die Zeit gemessen.
Vor den Abschnitt XStart(num) und danach XStop(num).
Aufpassen muß man aber bei Exit, Break, Continue, sowie bei Exceptions.


Jetzt siehst du paktisch, wo wieviel Zeit (in Millisekunden) verloren geht.
Delphi-Quellcode:
ZeroMemory(@XXX, SizeOf(XXX)); ///////// initialisieren /////////////////////////////

// Einzelne Texte zusammensetzen
    begin
XStart(0);
      quelle:= tstringlist.create;
      ziel:= tstringlist.create;

      try
XStart(1);
        //Previewdatei laden
        quelle.LoadFromFile(extractfilepath(application.exename) + 'preview2.dat');
XStop(1);

XStart(2);
        //Ersetzen von zwei Zeichen, da sich ansonsten im weiteren Analyseverlauf nicht korrekt verarbeitet werden; umständlich, aber anders weiß ichs nich..
        quelle.Text:=stringreplace2(quelle.text, '"', 'ANFUEEEE');
        quelle.Text:=stringreplace2(quelle.text, #39, 'EINFANFUEEEE');
XStop(2);

XStart(3);
        for ii:=0 to quelle.Count-1 do
          begin
XStart(4);
          wortarttemp:= gibmirwortart(quelle.strings[ii], #9);
XStop(4);

XStart(5);
          //Token zusammennehmen
          if pos('#' + wortarttemp + '#', tok)<>0 then //Bedingung; braucht keine Zeit, da der zu durchsuchende String tok nur ~40 Zeichen groß ist
            ziel.text:= ziel.text + gibmirtoken(quelle.strings[ii], #9);
XStop(5);

XStart(6);
          //Lemma zusammennehmen
          if pos('#' + wortarttemp + '#', lem)<>0 then //s.o.
            begin
XStart(7);
              lemmareal:= gibmirlemma(quelle.strings[ii], #9);
              schon:= 0;
XStop(7);

XStart(8);
              if (lemmareal= '<UNKNOWN>') and (checkbox2.checked) then //weitere Bedingungen
                begin
                ziel.text:= ziel.text + gibmirtoken(quelle.strings[ii], #9);
                schon:= 1;
                end;
XStop(8);

XStart(9);
              if (lemmareal= '@card@') and (checkbox4.checked) then
                begin
                ziel.text:= ziel.text + gibmirtoken(quelle.strings[ii], #9);
                schon:= 1;
                end;
XStop(9);

XStart(10);
              if (lemmareal= 'CARD') and (checkbox4.checked) then
                begin
                ziel.text:= ziel.text + gibmirtoken(quelle.strings[ii], #9);
                schon:= 1;
                end;
XStop(10);

XStart(11);
              if (lemmareal= '@ord@') and (checkbox4.checked) then
                begin
                ziel.text:= ziel.text + gibmirtoken(quelle.strings[ii], #9);
                schon:= 1;
                end;
XStop(11);

XStart(12);
              if schon=0 then ziel.text:= ziel.text + lemmareal;
XStop(12);
            end;
XStop(6);

XStart(13);
          //Wortart zusammennehmen
          if pos('#' + wortarttemp + '#', poss)<>0 then //s.o.
            ziel.Text:= ziel.text + gibmirwortart(quelle.strings[ii], #9);
XStop(13);

         end;
XStop(3);

XStart(14);
        //Wenn die Stringlist quelle durchgearbeitet ist und aller relevanten Strings in ziel, dann sollen die Strings in ziel zu einem fortlaufenden Text (-> zielende: string;) zusammengesetzt werden
        for x:=0 to ziel.Count-1 do
          zielende:= zielende + ' ' + ziel.Strings[x];
XStop(14);

XStart(15);
        //Vorherige Ersetzungen rückgängig machen
        zielende:= stringreplace2(zielende, 'ANFUEEEE', '"');
        zielende:= stringreplace2(zielende, 'EINFANFUEEEE', #39);
XStop(15);

XStart(16);
        //Ergebnis (Preview) in Memo ausgeben
        memo2.text:= zielende;
XStop(16);

      finally
        quelle.free;
        ziel.Free;
      end;
XStop(0);

XShow; ///////// Ergebnis ausgeben /////////////////////////////

################################################################################

//Funktion für die Ersetzung; ist schneller als die alte stringreplace
function stringreplace2(aString, FromStr, ToStr: AnsiString): AnsiString;
var
   I: Integer;
begin
XStart(31);
  // check whether string are equal
   if FromStr = ToStr then
   begin
      Result := aString;
XStop(31);
      Exit;
   end;
   Result := '';
  // find fromstr
   I := Pos(FromStr, aString);
   while I > 0 do
   begin
    // copy all characters prior fromstr
      if I > 1 then
         Result := Result + Copy(aString, 1, I - 1);
    // append tostr
      Result := Result + ToStr;
    // delete all until after fromstr
      Delete(aString, 1, I + Length(FromStr) - 1);
    // find next fromstr
      I := Pos(FromStr, aString);
   end;
   Result := Result + aString;
XStop(31);
end;

//hier wird die zweite Stelle des durch tab geteilten Strings aus quelle ermittelt
function gibmirwortart(s:string; sep:char) :string;
var
  t: Tstringlist;
begin
XStart(32);
  //hier muss jetzt das zweite Wort rausgefiltert werden
  t:= tstringlist.create;
  try
  extractstrings([char(sep)], [' '], pchar(s), t);
  result:= t.Strings[1];
  finally
  t.free;
  end;
XStop(32);
end;

//hier wird die erste Stelle des durch tab geteilten Strings aus quelle ermittelt
function gibmirToken(s:string; sep:char) :string;
var
  t: Tstringlist;
begin
XStart(33);
  //hier muss jetzt das zweite Wort rausgefiltert werden
  t:= tstringlist.create;
  try
  extractstrings([char(sep)], [' '], pchar(s), t);
  result:= t.Strings[0];
  finally
  t.free;
  end;
XStop(33);
end;

//hier wird die dritte Stelle des durch tab geteilten Strings aus quelle ermittelt
function gibmirLemma(s:string; sep:char) :string;
var
  t: Tstringlist;
begin
XStart(34);
  //hier muss jetzt das zweite Wort rausgefiltert werden
  t:= tstringlist.create;
  try
  extractstrings([char(sep)], [' '], pchar(s), t);
  result:= t.Strings[2];
  finally
  t.free;
  end;
XStop(34);
end;

p80286 12. Feb 2010 17:50

Re: TStringlist mit 60000 Einträgen zu langsam
 
Ein beinahe OT:

ich hatte heute eine Stringlist mit ca 200 000 Einträgen (Regestry Schlüssel) (ca 7 MB), die waren nach ca 2 Min. durch den Datenwolf gedreht, incl. Schreiben was gefühlt beinahe die Hälfte der Zeit ausgemacht hat.
( ein bisschen copy(), pos() sowie tstringlist.delete und stringlist.add )

Also die anfänglichen 5 Minuten sind der blanke Horror

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 Uhr.
Seite 5 von 5   « Erste     345   

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