AGB  ·  Datenschutz  ·  Impressum  







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

Große Textdateien spitten

Ein Thema von muhael · begonnen am 29. Okt 2017 · letzter Beitrag vom 30. Okt 2017
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
muhael

Registriert seit: 5. Mär 2013
42 Beiträge
 
#1

Große Textdateien spitten

  Alt 29. Okt 2017, 18:20
Delphi-Version: 7
Hallo DP Team,

ich habe eine Funktion die große Textdateien in 4 Dateien splittet.
Nur diese Funktion ist "sehr" langsam, Sie benötigt für eine 1,5 GB große Textdatei 102 Sekunden.
Da die Dateien die mein Programm bearbeiten soll ungefähr in der Größenordnung von 3-4 GB liegen, braucht die Funktion dafür ca 4,5 Minuten und dies ist zu lang.

Gibt es eine Möglichkeit oder eine Funktion die das wesentlich schneller machen kann?
Wichtig zu wissen ist, dass die Datei nur Zeilenweise gesplittet werden kann.


Hier der Funktionscode;

Delphi-Quellcode:
  For i := 0 to 3 do
  begin
    AssignFile(F[i],ExtractFilePath(ParamStr(0)) + 'Test_' + IntToStr(i) + '.txt');
    ReWrite(F[i]);
  end;

  i := 0;
  AssignFile(ff,Epfad.Text);
  Reset(ff);
  while not eof(ff) do
  begin
    inc(i);
    ReadLn(ff, TestText);
    Case i of
      1: WriteLn(F[0],TestText);
      2: WriteLn(F[1],TestText);
      3: WriteLn(F[2],TestText);
      4: WriteLn(F[3],TestText);
    end;
    If i = 4 Then
      i := 0;
  end;
  CloseFile(F[0]);
  CloseFile(F[1]);
  CloseFile(F[2]);
  CloseFile(F[3]);
VG

Vielen Dank und Grüße
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 18:29
Wie lang sind die Zeilen?

Die einfachste Variante würde eine Vergrößerung des Caches bedeuten.
Die Uralten Funktionen AssignFile+TEXT nutzen einen Cache von 128 Byte je Datei und das ist natürlich extrems unökonomisch. (vorallem da alleine schon die Sektoren/Cluster des Datenträgers wesentlich größer sind)

Siehe OH von Reset/Rewrite.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#3

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 18:31
Sehe ich das richtig: jede Zeile kommt in eine andere Datei und nach 4 Zeilen fängt es wieder von vorne an? In dem Fall kommst du um ein zeilenweises Lesen, wie es aktuell implementiert ist, wohl nicht herum.

Man könnte allenfalls noch was mit Textbuffern machen: Delphi-Referenz durchsuchenSetTextBuf
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
muhael

Registriert seit: 5. Mär 2013
42 Beiträge
 
#4

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 18:35
Wie lang sind die Zeilen?
Unterschiedlich groß. Die längste Zeile in meiner Testdatei ist 409 Zeichen lang.
Es kann aber sein, dass die Zeilen länger werden, da es sich um eine Fehlerdatei einer Datenintegritätsprüfung einer Datenbank handelt.

Hier mal eine Beispielzeile:
Warnung: 'Fibu Buch.-Blattname' existiert nicht. Buch.-Blattvorlagenname: ALLGEMEIN, Name: LOHN 02/06 Das Feld Buch.-Blattname in der Tabelle Fibu Buch.-Blattzeile hat eine Tabellenrelation auf das Feld Name in der Tabelle Fibu Buch.-Blattname. 'Fibu Buch.-Blattzeile' ist durch die folgenden Felder und Werte bestimmt: Buch.-Blattvorlagenname='ALLGEMEIN',Buch.-Blattname='LOHN 02/06',Zeilennr.='337000'




Sehe ich das richtig: jede Zeile kommt in eine andere Datei und nach 4 Zeilen fängt es wieder von vorne an? In dem Fall kommst du um ein zeilenweises Lesen, wie es aktuell implementiert ist, wohl nicht herum.
Ungefähr ja, so war meine erste Idee.

Mein Programm analysiert diese Zeilen und diesen Prozess will ich beschleunigen indem ich die Datei in 4 gleich große Dateien splitte und in 4 Threads gleichzeitig bearbeite.
  Mit Zitat antworten Zitat
Rollo62
Online

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#5

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 18:40
Vielleucht könnte TStringReader schneller sein (glaub ich aber nicht), gibt es das in D7 ?
https://stackoverflow.com/questions/...iles-in-delphi

Ich würde eher versuchen Chunks in M;emory einzulesen, und die dann im Memory zu analysieren.

Rollo
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 20:19
Um es zu Beschleunigen willst du es also 5 Dateien lesen und 4 Dateien auf die "langsame" Platte schreiben?

Warum nicht die Datei einmal einlesen und dabei die gelesenen Zeilen direkt an die Threads weiterreichen?
$2B or not $2B

Geändert von himitsu (29. Okt 2017 um 20:22 Uhr)
  Mit Zitat antworten Zitat
muhael

Registriert seit: 5. Mär 2013
42 Beiträge
 
#7

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 20:23
Um es zu Beschleunigen willst du es also 5 Mal lesen und 4 Mal auf die "langsame" Platte schreiben?

Warum nicht die Datei einmal einlesen und dabei die gelesenen Zeilen direkt an die Threads weiterreichen?

Ich speichere ja die Werte zurück und Überprüfe daraufhin auf doppelte Werte. Da müssen ja dann die threads drauf warten bis die Überprüfung von einem thread fertig ist oder? 🤔
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#8

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 20:28
Wie wäre es denn mit Memory Mapped Files von Herrn Jaenike?
Ließt unheimlich schnell ein und die Zeilen stehen auch schnell zur Verfügung.

http://www.delphipraxis.net/151898-s...ei-reader.html
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#9

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 20:39
Hab' mal ein bisserl rumgespielt, rausgekommen ist dashier:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes;

const
// BUFFER_SIZE = 16384; // 1:19
// BUFFER_SIZE = 65536; // 1:07
// BUFFER_SIZE = 65536 * 2; // 1:03
  BUFFER_SIZE = 65536 * 4; // 0:53
// BUFFER_SIZE = 65536 * 8; // 2:07
  arLow = 0;
  arHigh = 3;
var
  i : Integer;
  f : array[arLow..arHigh] of TextFile;
  ff : TextFile;
  inf_buf : array[1..BUFFER_SIZE] of Byte;
  utf_buf : array[1..BUFFER_SIZE] of Byte;
  sIn : String;
  sOut : Array[arLow..arHigh] of String;
  sZeile : String;
  dtStart : TDateTime;
  dtEnde : TDateTime;
begin
  dtStart := Now;
  WriteLn('Start : ' + DateTimeToStr(dtStart));
  sIn := ParamStr(1);

  For i := Low(f) to High(f) do begin
    sOut[i] := ExtractFilePath(ParamStr(0)) + 'Test_' + IntToStr(i) + '.txt';
    AssignFile(F[i],sOut[i]);
    SetTextBuf(F[i],utf_buf, BUFFER_SIZE);
    ReWrite(F[i]);
  end;

  i := 0;
  AssignFile(ff,sIn);
  SetTextBuf(ff,inf_buf,BUFFER_SIZE);
  Reset(ff);
  while not eof(ff) do begin
    ReadLn(ff, sZeile);
    WriteLn(F[i],sZeile);
    inc(i);
    If i > arHigh Then i := arLow;
  end;
  dtEnde := Now;
  WriteLn('Ende : ' + DateTimeToStr(dtEnde));
  WriteLn('Zeit : ' + TimeToStr(dtEnde - dtStart));
  WriteLn('Buffer: ' + IntToStr(Buffer_Size));
  WriteLn('Dateigroessen:');
  WriteLn('Eingabe: ',FileSize(ff) * Buffer_Size,' (',sIn,')');
  CloseFile(ff);
  for i := Low(f) to High(f) do begin
    WriteLn('Ausgabe: ',FileSize(f[i]) * Buffer_Size,' (',sOut[i],')');
    CloseFile(F[i]);
  end;
end.
Hinter der Konstante Buffer_Size steht jeweils, wielange mein Rechner für die Aufteilung einer Datei von 1.250.375.501 Byte benötigt hat.

Eventuell kannst Du damit ja was anfangen.
  Mit Zitat antworten Zitat
muhael

Registriert seit: 5. Mär 2013
42 Beiträge
 
#10

AW: Große Textdateien spitten

  Alt 29. Okt 2017, 21:03
Hallo Nahpets,

Ich konnte damit die benötigte Zeit von 102 Sekunden auf 25 Sekunden verringern.

Vielen Dank

Start : 29.10.2017 20:59:44
Ende : 29.10.2017 21:00:10
Zeit : 00:00:25
Buffer: 262144
Dateigroessen:
Eingabe: 1535639552 (TestDaten\dbtest_PINAG.txt)
Ausgabe: 383778816 (Test_0.txt)
Ausgabe: 383778816 (Test_1.txt)
Ausgabe: 383778816 (Test_2.txt)
Ausgabe: 383778816 (Test_3.txt)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


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 14:25 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