AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TStringlist mit 60000 Einträgen zu langsam

Ein Thema von friedemann2009 · begonnen am 10. Feb 2010 · letzter Beitrag vom 12. Feb 2010
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#31

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 15:25
Zitat von Hawkeye219:
Warum nimmst du eigentlich den Umweg über eine Stringliste? Am Ende fügst du ja doch wieder alles zu einem einzelnen String zusammen.
Hallo Hawkeye, das gleiche frage ich ja bezüglich der Eingangsdaten, aber das wird entweder niedergemacht oder ignoriert - statt einfach weitere Zeilen an den Ausgangsdatei anzuhängen (simples Schreiben in eine Datei), muss mit hundertausenden von stringreplace-Aufrufen dafür gesorgt werden, das das Ergebnis am Ende so aussieht, wie es ohne jeden Aufwand von vornherein hätte aussehen können.

Eine einfache readln - verarbeiten - writeln Sequenz ist zwar viel effektiver, aber verpönt.

Zitat von friedemann2009:
@Reinhart, was meinst du damit?

Gruß, friedemann
Hallo Friedemann, wie du siehst, kann man das hier im Forum nicht besprechen, einfache und effektive Programme sind bei der überwiegenden Mehrheit absolut unerwünscht. Also vergiss es einfach.

Gruss Reinhard
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.182 Beiträge
 
Delphi 12 Athens
 
#32

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 15:54
Zitat von Reinhard Kern:
Hallo Friedemann, wie du siehst, kann man das hier im Forum nicht besprechen, einfache und effektive Programme sind bei der überwiegenden Mehrheit absolut unerwünscht. Also vergiss es einfach.
Ideal wäre es mal, OOP-mäßig eine neue Klasse zu erstellen, welche die Vorteile der "alten" Pascalfunktionen mit einigen Verbesserungen/Optimierungen vereint.
Also eine Art TStringStream, welchen man an alle möglichen Streams ranhängen kann.
Vorallem an TFileStream und TMemoryStream.

Ja, es gibt einen TStringStream, aber der ist ja wohl ein Witz.

Ideen dafür existieren schon länger, aber ich hatte nie einen Grund, dieses mal zu machen.


Ein großes Problem exisitert nämlich, denn mit den alten Pascal-Routinen kann man selbst ab D2009 nur ANSI-Dateien erstellen und auslesen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#33

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 16:31
Hallo,
Zitat von himitsu:
Ideal wäre es mal, OOP-mäßig eine neue Klasse zu erstellen, welche die Vorteile der "alten" Pascalfunktionen mit einigen Verbesserungen/Optimierungen vereint.
Also eine Art TStringStream, welchen man an alle möglichen Streams ranhängen kann.
Vorallem an TFileStream und TMemoryStream.
auch wenn es dem TE aufgrund seiner eingesetzten Delphi-Version nicht hilft, passt es thematisch noch in diesen Thread:

TStreamReader/TStreamWriter
TStringReader/TStringWriter

Gruß Hawkeye
  Mit Zitat antworten Zitat
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#34

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 16:32
Zitat von himitsu:
Ein großes Problem exisitert nämlich, denn mit den alten Pascal-Routinen kann man selbst ab D2009 nur ANSI-Dateien erstellen und auslesen.
Falls das ein Problem ist oder wird, es soll auch unter Windows API Möglichkeiten geben, aus einer Datei zu lesen. Klassen für Textdateien bzw. eine Hierarchie davon habe ich mir auch schon erstellt, dabei habe ich teilweise auch eigene readln und writeln Prozeduren verwendet; das ist ja schliesslich kein Hexenwerk, das nur Borlandprogrammierer hinkriegen.

Gruss Reinhard
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#35

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 16:39
Hallo zusammen,
ist ja richtig was los hier.

wie ja schon mehrmals angemerkt wurde ist
Delphi-Quellcode:
function gibmirLemma(s:string; sep:char) :string;
var
  t: Tstringlist;
begin
  //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;
end;
nicht so optimal.

wie wäre denn z.B. so etwas:
Delphi-Quellcode:
function gibmirLemma(s:string; sep:char) :string;
var
  pp : integer;
begin
  result:='';
  //hier muss jetzt das zweite Wort rausgefiltert werden
  pp:=pos(sep,s);
  if pp>0 then begin
    pp:=posex(sep,s,pp+1);
    if pp>0 then
      result:= copy(s,pp+1,255);
  end;
end;
@reinhard
Auch wenn ich Dir im Prinzip zustimme, TStringlist ist einfach genial, besonders wenn die Verarbeitung ein satz vor zwei Satz zurück, einen löschen läuft.

Wenn es wirklich nur darum geht (und das hab ich noch nicht erkannt) einen Satz nach dem anderen zu lesen, zu filetieren und dann wegzuschreiben/an einen String anzuhängen würde ich Dich inhaltlich voll unterstützen.

und verlier bitte den Unterschied nicht aus den Augen:

Delphi-Quellcode:
var
  sl=tstringlist;


sl:=tstringlist.create;
...
sl.loadfromfile('MeineDaten');
for i:=0 to sl.count-1 do
  irgendwas
sl.free;
Delphi-Quellcode:
var
  f : textfile;
  buffer : array [0..8191] of byte;
  satz : string


assign(f,'MeineDaten');
settextbuf(f,buffer,sizeof(buffer));
reset(f);
repeat
  readln(f,satz);
  machwwasmitsatz
unil eof(f);
closefile(f);
Die zweite Möglichkeit ist doch wesentlich aufwendiger.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.858 Beiträge
 
Delphi 11 Alexandria
 
#36

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 19:11
Hallo friedemann2009,

wie viel Speicher verbrauchst Du für die 100.000 Einträge?
Welches Windows ist auf dem Rechner installiert?

Die geringe Geschwindigkeit könnte auch von Windows verursacht werden, wenn zu viel Speicher belegt wird. Wenn der Speicher voll ist, fängt Windows an Teile davon auf die Festplatte auszulagern.

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#37

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 23:11
Hallo,
jetzt geb ich auch mal meinen Senf dazu.
Das was hier die meiste Zeit braucht sind doch die vielen gibmir... Aufrufe.

Hier wie ich es machen würde:
Delphi-Quellcode:
    begin
      quelle := tstringlist.create;
      ziel := tstringlist.create;
      eineZeile := tstringlist.create;
      try
        //Previewdatei laden
        quelle.LoadFromFile(extractfilepath(application.exename) + 'preview2.dat');

        eineZeile.Delimiter := #9;
        eineZeile.QuoteChar := '"'; // hier bin ich mir nicht sicher ob das reicht um die stringreplace überflüssig zu machen

        for i := 0 to quelle.Count - 1 do
        begin
          // vorsichtshalber säubern, muß aber nicht sein
          eineZeile.Clear;
          // nur 1 mal parsen (und das von Delphi selbst) statt x mal immerwieder
          // hier kann wahlweise auch mit readln gearbeitet werden wenn man will
          eineZeile.DelimitedText := quelle.Strings[i];

          //Token zusammennehmen
          if pos('#' + eineZeile[1] + '#', tok) <> 0 then
            ziel.text:= ziel.text + eineZeile[0];

          //Lemma zusammennehmen
          if pos('#' + eineZeile[1] + '#', lem) <> 0 then
            begin
              schon := 0;

              if eineZeile[2] in ['<UNKNOWN>', '@card@', 'CARD', '@ord@'] then
              begin
                if (eineZeile[2] = '<UNKNOWN>') then
                begin
                  if checkbox2.checked then
                  begin
                    ziel.text := ziel.text + eineZeile[0];
                    schon := 1;
                  end;
                end
                else // alle anderen
                begin
                  if checkbox4.checked then
                  begin
                    ziel.text := ziel.text + eineZeile[0];
                    schon := 1;
                  end;
                end;
              end;

              if schon = 0 then
                ziel.text := ziel.text + eineZeile[2];
            end;

          if pos('#' + eineZeile[1] + '#', poss) <> 0 then
            ziel.Text := ziel.text + eineZeile[1];
         end;

        for i := 0 to ziel.Count - 1 do
          zielende := zielende + ' ' + ziel.Strings[i];

        memo2.text := zielende;

      finally
        quelle.Free;
        ziel.Free;
        eineZeile.Free;
      end;
Damit wird nur 1 mal geparst und dann auf die Teile direkt zugegriffen.
Ob das jetzt 100 pro funktioniert kann ich aber nicht so aus dem Hut sagen.

Um zur Diskusion beizutragen: soweit ich mich erinnern kann nutzt LoadFromFile u.Ä. die Windows API für das eigentliche Ansprechen der Datei, während readln eine Delphi (besser Pascal) eigene Umsetzung der gleichen Funktion ist. An dieser Stelle lässt sich darüber streiten, ob die Windows eigene oder die Borland/CodeGear/Embarcadero umsetzung der selben schneller ist. Ich bin ja (auch wenn ich das sonst nicht so sehe) eher für MS, alleine durch die Tatsache das MS die Funktionen auf die jeweilige Windows Version anpassen kann und Delphi von der Plattform wo das Programm dann läuft zur Compiletime keine Ahnung haben kann.

Bis Dann, und hoffentlich konnte ich helfen,
David

Nachtrag: Ich hab nochmal zusammegerechnet, du zerpflückst jede Zeile 5 mal, da hast du dein Performanceproblem. Wenn es so wie in meinem Code nicht geht kannst du auch eine Funktion schreiben die alle 3 Teile auf einmal zurückgibt und dann im "Hauptprogramm" in 3 einzelne Variablen speichert. So in etwa:
Delphi-Quellcode:
procedure aufteilen(const s : string; const sep : char; var Token, wortart, Lemma : string);
var
  t: Tstringlist;
begin
  //hier muss jetzt das zweite Wort rausgefiltert werden
  t:= tstringlist.create;
  try
    extractstrings([char(sep)], [' '], pchar(s), t);
    Token := t.Strings[0];
    wortart := t.Strings[1];
    Lemma := t.Strings[2];
  finally
    t.free;
  end;
end;

// so wirds dann benutzt, einmal am Anfang
aufteilen(quelle.strings[ii], #9, token_Variable, wortarttemp, lemmareal);
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#38

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 23:35
Eventuell tut es in diesem speziellen Fall auch schon meineStringliste.sorted := true; ?
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#39

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 11. Feb 2010, 23:38
Die Sortierung ist, glaube ich, schon wichtig. Mit .sorted := true; geht die verloren.
  Mit Zitat antworten Zitat
friedemann2009

Registriert seit: 10. Feb 2010
49 Beiträge
 
#40

Re: TStringlist mit 60000 Einträgen zu langsam

  Alt 12. Feb 2010, 13:31
Zitat von Chemiker:
Hallo friedemann2009,

wie viel Speicher verbrauchst Du für die 100.000 Einträge?
Welches Windows ist auf dem Rechner installiert?

Die geringe Geschwindigkeit könnte auch von Windows verursacht werden, wenn zu viel Speicher belegt wird. Wenn der Speicher voll ist, fängt Windows an Teile davon auf die Festplatte auszulagern.

Bis bald Chemiker
Also wenn ich es richtig verfolge, wird nichts ausgelagert. Windoof XP prof. Ich fürchte auch, dass es an den "gibmir"-Funktionen und dem Replace liegt. Ich bin am Nachprobieren, was hier so bisher geschrieben wurde.

Danke und Gruß,
friedemann


NACHTRAG:

- Falls ich es noch nicht schrieb: Thanks a lot für die vielen Hinweise!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:38 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