![]() |
Delphi-Version: 7
Zeile aus Stringlist löschen, wie optimieren?
Hallo zusammen,
ich muß des öfteren aus recht größen Textdateien bestimmte Zeilen löschen. Dies mache ich z.Zt. so {leerzeilen löschen}
Delphi-Quellcode:
Hat man mehr als 1 Mio Zeilen, kann das schon dauern. Darum meine Frage, wie kann ich das optimieren?
Stringliste.loadfromfile('Testdatei');
.. for i:=Stringliste.count-1 downto 0 do if length(Stringliste[i])=0 then Stringliste.delete(i); Ein etwas besseres Laufzeitverhalten habe ich mit
Delphi-Quellcode:
(das Verhältnis ist etwa 6:5)
for i:=Stringliste.count-1 downto 0 do begin
if length(Stringliste[i])>0 then stringlist2.insert(0,stringlist[i]); Stringlist.delete(i); end; Als untauglich hat sich erwiesen:
Delphi-Quellcode:
Da beim TStringlist.Delete letztlich nur 3 Pointer verschoben werden erhoffe ich mir von einer Pointerliste auch keine große Verbesserung.
p:=pos(#13#10#13#10,string);
while p>0 do begin delete(string,p,2); p:=posex(#13#10#13#10,string,p-1); end Habt Ihr noch eine Idee wie ich da etwas Tempo machen kann? Gruß K-H |
AW: Zeile aus stringlist löschen wie optimieren
Deine for-Schleifen haben weder eine Richtung noch eine Ende-Bedingung und compilieren somit nicht. Beim Löschen von Einträgen ist aber die Laufrichtung der Schleife schon relevant.
Berücksichtigst du bei deinen Zeitmessungen auch das Laden und Speichern oder nur die Schleife? |
AW: Zeile aus stringlist löschen wie optimieren
Zitat:
(die paar Sekunden für das Laden kann man ignorieren) Beim letzten Lauf ging es um 20 Mio. Zeilen und ca 1,8 Gbyte. Gruß K-H |
AW: Zeile aus Stringlist löschen, wie optimieren?
Ich hätte gesagt, das liegt in der Natur von
Delphi-Quellcode:
, oder? Ohne es genau zu wissen hätte ich doch gesagt, das es intern auf ein dynamisch wachsendes/schrumpfendes Array abgebildet wird. Löscht du mittendrin eins raus, rückt alles auf.
TStringList
Nehme ich eine TStringList bzw eine TList<String> aus der RTL, brauche ich ca 22 Sekunden um auf 5 Mio. Strings ca 2. Mio zufällige herauszulöschen. Nehme ich als Container, nur als Beispiel, ein
Delphi-Quellcode:
, sind es 1500ms.
Spring.Collections.ISet<String>
Deshalb würde ich bei solchen Datenmengen nach einem anderen Container suchen - Falls meine Annahme den zutrifft, dass es intern ein großes Array ist. Wahrscheinlich wäre es ebenso schneller, wenigstens eine Kopie der TStringList zu bauen: Über alle Elemente drüberruschen und in die Kopie nur die aufnehmen, die nicht leer sind. |
AW: Zeile aus Stringlist löschen, wie optimieren?
Delphi-Quellcode:
wobei ich keine Ahnung habe ob eine Prüfung auf trim oder length schneller ist...
i := 0;
while i < Stringliste.Count do if trim(Stringliste[i]) = '' then Stringliste.Delete(i) else inc(i); |
AW: Zeile aus Stringlist löschen, wie optimieren?
Aber der Flaschenhals ist doch
Delphi-Quellcode:
, oder?
TStringList.Delete(..)
|
AW: Zeile aus Stringlist löschen, wie optimieren?
Ich mache seit einiger Zeit Löschvorgänge/Überarbeitungen in großen Textdateien auch mit einer zweiten Stringliste, in die ich nicht zu löschende/überarbeitete Strings mit Stringliste2.Add() hinzufüge. Dabei hat sich eine Beschleunigung um den Faktor ~10 ergeben im Vergleich zum Löschen der Einträge mit Delete() in der Originalliste.
Die Dateien haben bei mir eine Größenordnung von 1-5 Mio. Zeilen (TTCN-Sourcecodes). |
AW: Zeile aus Stringlist löschen, wie optimieren?
Wenn es nur darum geht ein paar Zeilen zu löschen und die Datei wieder wegzuschreiben, warum schreibst du nicht einfach die TStringList ohne die Zeilen wieder zeilenweise weg? Was anderes macht die doch intern logischerweise beim Speichern auch nicht.
Zudem wäre es denke ich sinnvoller per MMF zuzugreifen und die ganzen Inhalte gar nicht erst als Strings in den Speicher zu laden. Das zeilenweise Einlesen siehst du z.B. hier: ![]() |
AW: Zeile aus Stringlist löschen, wie optimieren?
Zur Info:
Delphi-Quellcode:
Grund:
if length(Stringliste[i])=0 then // ist langsamer als
if Stringliste[i] = '' then // als der direkte Vergleich auf einen leeren String Der Aufruf der
Delphi-Quellcode:
-Funktion benötigt mehr CPU-Befehle als wenn nur der String (was ja nur ein Zeiger auf eine Datenstruktur ist) auf NIL überprüft wird.
Length()
|
AW: Zeile aus Stringlist löschen, wie optimieren?
waru teilst du den Inhalt der Liste in verschiedene auf ?
so läuft du in deiner For schleife mehere Teile des Textes gleichzetig durch; via Case länge ermitteln und daraufhin die anzahl der Listen anpassen. fertiiiisch |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:18 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 by Thomas Breitkreuz