![]() |
Re: TStringlist mit 60000 Einträgen zu langsam
Zitat:
Eine einfache readln - verarbeiten - writeln Sequenz ist zwar viel effektiver, aber verpönt. Zitat:
Gruss Reinhard |
Re: TStringlist mit 60000 Einträgen zu langsam
Zitat:
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. :oops: Ein großes Problem exisitert nämlich, denn mit den alten Pascal-Routinen kann man selbst ab D2009 nur ANSI-Dateien erstellen und auslesen. |
Re: TStringlist mit 60000 Einträgen zu langsam
Hallo,
Zitat:
![]() ![]() Gruß Hawkeye |
Re: TStringlist mit 60000 Einträgen zu langsam
Zitat:
Gruss Reinhard |
Re: TStringlist mit 60000 Einträgen zu langsam
Hallo zusammen,
ist ja richtig was los hier. wie ja schon mehrmals angemerkt wurde ist
Delphi-Quellcode:
nicht so optimal.
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; wie wäre denn z.B. so etwas:
Delphi-Quellcode:
@reinhard
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; 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:
Die zweite Möglichkeit ist doch wesentlich aufwendiger.
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); Gruß K-H |
Re: TStringlist mit 60000 Einträgen zu langsam
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 |
Re: TStringlist mit 60000 Einträgen zu langsam
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:
Damit wird nur 1 mal geparst und dann auf die Teile direkt zugegriffen.
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; 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); |
Re: TStringlist mit 60000 Einträgen zu langsam
Eventuell tut es in diesem speziellen Fall auch schon
Delphi-Quellcode:
?
meineStringliste.sorted := true;
|
Re: TStringlist mit 60000 Einträgen zu langsam
Die Sortierung ist, glaube ich, schon wichtig. Mit .sorted := true; geht die verloren.
|
Re: TStringlist mit 60000 Einträgen zu langsam
Zitat:
Danke und Gruß, friedemann NACHTRAG: - Falls ich es noch nicht schrieb: Thanks a lot für die vielen Hinweise! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:14 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