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);