Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zeile aus Stringlist löschen, wie optimieren? (https://www.delphipraxis.net/179098-zeile-aus-stringlist-loeschen-wie-optimieren.html)

p80286 14. Feb 2014 10:57

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:
Stringliste.loadfromfile('Testdatei');
..
for i:=Stringliste.count-1 downto 0 do
  if length(Stringliste[i])=0 then Stringliste.delete(i);
Hat man mehr als 1 Mio Zeilen, kann das schon dauern. Darum meine Frage, wie kann ich das optimieren?

Ein etwas besseres Laufzeitverhalten habe ich mit
Delphi-Quellcode:
for i:=Stringliste.count-1 downto 0 do begin
  if length(Stringliste[i])>0 then stringlist2.insert(0,stringlist[i]);
  Stringlist.delete(i);
end;
(das Verhältnis ist etwa 6:5)


Als untauglich hat sich erwiesen:
Delphi-Quellcode:
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
Da beim TStringlist.Delete letztlich nur 3 Pointer verschoben werden erhoffe ich mir von einer Pointerliste auch keine große Verbesserung.

Habt Ihr noch eine Idee wie ich da etwas Tempo machen kann?

Gruß
K-H

Uwe Raabe 14. Feb 2014 11:02

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?

p80286 14. Feb 2014 11:22

AW: Zeile aus stringlist löschen wie optimieren
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1247854)
Berücksichtigst du bei deinen Zeitmessungen auch das Laden und Speichern oder nur die Schleife?

Es geht nur um die Schleife!
(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

Der schöne Günther 14. Feb 2014 11:25

AW: Zeile aus Stringlist löschen, wie optimieren?
 
Ich hätte gesagt, das liegt in der Natur von
Delphi-Quellcode:
TStringList
, 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.

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:
Spring.Collections.ISet<String>
, sind es 1500ms.

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.

user0815 14. Feb 2014 11:53

AW: Zeile aus Stringlist löschen, wie optimieren?
 
Delphi-Quellcode:
      i := 0;
      while i < Stringliste.Count do
      if trim(Stringliste[i]) = ''
       then Stringliste.Delete(i)
        else inc(i);
wobei ich keine Ahnung habe ob eine Prüfung auf trim oder length schneller ist...

Der schöne Günther 14. Feb 2014 12:03

AW: Zeile aus Stringlist löschen, wie optimieren?
 
Aber der Flaschenhals ist doch
Delphi-Quellcode:
TStringList.Delete(..)
, oder?

GPRSNerd 14. Feb 2014 12:15

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

jaenicke 14. Feb 2014 12:18

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:
http://www.delphipraxis.net/151898-s...ei-reader.html

sx2008 14. Feb 2014 13:12

AW: Zeile aus Stringlist löschen, wie optimieren?
 
Zur Info:

Delphi-Quellcode:
if length(Stringliste[i])=0 then  // ist langsamer als
if Stringliste[i] = '' then       // als der direkte Vergleich auf einen leeren String
Grund:
Der Aufruf der
Delphi-Quellcode:
Length()
-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.

Mokus 14. Feb 2014 13:32

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 23:18 Uhr.
Seite 1 von 3  1 23      

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