| 

.NET C# Java Javascript Exception

4
hallo,

ich möchte eine textdatei auslesen und die daten einer anderen textdatei hinzufügen!

es gibt bereits viele ansätze wie man das problem lösen kann, aber ich legen hierbei großen wert auf die performance da große mengen an daten verschoben werden sollen

die ausgangsdatei sollte zeilenweise ausgelesen werden und die zieldatei auch wieder zeilenweisen beschrieben

ist es sinnvoll hierfür alle daten erstmal in einer liste/dict/andere zwischenspeicher und dann wieder einzeln auszulesen?
17.02.2011
burner007 810 1 2 9
4 Antworten
1
Du willst letztlich den Overhead um die Bottlenecks "lesen", "bearbeiten" und "schreiben" reduzieren.

An diesem Punkt sehe ich spontan erstmal drei Möglichkeiten der Optimierung (in Abhängigkeit der Gewichtung der Bottlenecks) :

1. Pipelining (wenn I/O das bottleneck ist)

Du liest zeilenweise und pipest die Zeilen direkt weiter an den Bearbeiter, der wiederum direkt an die Ausgabe in die Datei piped. Das lässt sich mit Python mit den Generatoren schön lösen.
Somit hast du das Optimum entlang der I/O-Bottlenecks rausgeholt.
Problematisch wird es nur, wenn deine Ausgabe so langsam ist, dass sich die Zeilen im Bearbeiter stauen. Dann könntest du wieder das RAM Problem haben.

2. Parallelisierung (wenn die Bearbeitung das Bottleneck ist)

Wenn du mehrere Dateien als Input und/oder Output hast, kannst du an dieser Stelle noch parallelisieren. Du musst dann lediglich sicherstellen, dass du keine konkurrierenden Zugriffe auf die Ausgabefiles hast bzw. dass du diese Zugriffe durch Locks schützt.
Außerdem solltest du dich bei Python nicht mit dem GIL anlegen.

3. Splitting / Merging (wenn die Bearbeitung das Bottleneck ist)

Mit dieser Methode kommst du evtl.(!) um das Locking drum herum. Du teils die Files in n Zeilenblöcke auf und liest (readonly) parallel aus den Files und schreibst parallel in n Zieldateien. Anschließend machst du einen File-Merge. Evtl. ist dann aber der Merge sehr teuer.


Die Methoden kann man auch noch kombinieren. Allerdings hängt die Machbarkeit und der Performancegewinn dann doch zu speziell von deinem Anwendungsfall ab, als dass man hier den goldenen Weg vorschlagen kann.
17.02.2011
Matthias 208 4
1
danke für die ausführliche erklärung! da es sich bei mir immer um maximal 5000 zeilen handelt die verschoben werden müssen, denke ich ist das pipelining die beste methode! habe es auch schon bisher mit ein paar hundert zeilen getestet und bin zufrieden mit der performance!

würdest du mir da zustimmen?
burner007 17.02.2011
ja, ich denke, das sollte zu handlen sein (vorausgesetzt deine Zeilen sind nicht ewig lang). wenn du mehrere jobs gleichzeitig ausführen kannst, dann kannst du in gesamtheit noch mehr gewinnen. du solltest den worst-case für den RAM vorher nachrechnen.
Matthias 17.02.2011
1
Eine höhere Performance solltest Du erreichen, wenn Du die Datei blockweise einliesst, dann diesen Block zeilenweise verarbeitest und anschliessend wieder zeilenweise oder eben als Block speicherst.
Wenn Du immer eine Zeile liest und dann diese wieder in die Zieldatei schreibst, dürftest Du viel Zeit wg. der Seeks auf der Festplatte verlieren.
17.02.2011
Torsten Weber 691 1 8
1
wenn ich ca. 5000 zeilen in der ausgangsdatei habe, wären dann blöcke von 500 zeilen angebracht, oder sogar 1000 besser, oder mehr/weniger? hast du da erfahrungen?
burner007 17.02.2011
1
Es kommt sehr darauf an, was Du mit diesen Zeilen veranstaltest und ob Du Entscheidungen treffen musst, die es möglicherweise sogar erforderlich machen mindestens 50 Zeilen im Speicher zu haben. Letztendlich ist es sehr speziell. Du dürftest aber die höchste Leseperformance erreichen, wenn die Blockgröße (Bytes nicht Zeilen) optimal auf das Device angepaßt ist, von dem Du versuchst zu lesen. Es spricht ja eigentlich nichts dagegen die Daten binär zu lesen, diese aber dann trotzdem in der Anwendung zeilenweise zu verarbeiten.
Torsten Weber 17.02.2011
0
Das ist eher nicht sinnvoll, denn bei großen Datenmengen läuft dein ram voll...
einfach eine zeile einlesen, diese bearbeiten und in die neue Datei schreiben
das würd ich für am sinnvollsten halten ;)

alles einlesen geht nur bei sehr kleinen datenmengen...
17.02.2011
DerPunk 1,2k 1 7
1
aber auf diese weise läuft der prozess recht langsam, da das lesen und schreiben viel zeit beansprucht
burner007 17.02.2011
hmmm...
Als Tipp hätt ich sonst nurnoch, Talend Open Studio zu benutzen, das is auf sowas genau ausgelegt, damit kann man mehrere millionen Reihen pro Sekunde schreiben ;-)
DerPunk 17.02.2011
1
danke für den tipp, aber das übersteigt den aufwand für eine funktion doch ein wenig ;)
burner007 17.02.2011
0
Auf welchem OS arbeites du?
Wenn du das auf einem Linux System durchführst, warum must du eine Programmiersprache nutzten? Werden die Zeilen noch in irgendeiner Weise manipuliert?
Du könntest das ganze auch auf der Konsole mit cat File.txt >> File2.txt realisieren.
Selbstverständlich kann man das auch aus Python triggen:
#!/bin/env python
#
import os
os.system('cat File.txt >> File2.txt ')

Somit lagerst du den Prozess ans OS aus, was deutlich schneller sein sollte.
23.12.2011
XJenso 332 7

Stelle deine File-Frage jetzt!