2017-09-04 3 views
0

ich eine große Textdatei über mehrere GBs lesen möchten lesen und es ohne das Laden der gesamten Datei aber Laden Brocken davon verarbeiten. (Verarbeitung beinhaltet Instanzen Wortzählung)vs Random Mit NIO Stücke von Dateien

Wenn ich Verwenden Sie eine gleichzeitige Hash-Map, um die Datei parallel zu verarbeiten, um sie effizienter zu machen. Gibt es eine Möglichkeit, NIO oder eine Direktzugriffsdatei zu verwenden, um sie in Blöcken zu lesen? Wäre es noch effizienter?

Die aktuelle Implementierung eines gepufferten Leser verwendet, die etwas geht:

while(lines.size() <= numberOfLines && (line = bufferedReader.readLine()) != null) { 
    lines.add(line); 
} 

lines.parallelStream().. // processing logic using ConcurrentHashMap 
+1

Entscheiden Sie sich. Welches ist es? NIO? Oder 'RandomAccessFile'? In jedem Fall können Sie Millionen von Zeilen pro Sekunde mit 'BufferedReader' lesen. Sie werden nicht mehr als sagen, 20% schneller mit NIO, und es wird * langsamer * mit 'RandomAccessFile', da es keine Pufferung gibt: und Multi-Threading kann es schlimmer machen oder gar nichts tun , da die Festplatte nicht multi-threaded ist. Müssen Sie das wirklich tun? – EJP

+0

Ich denke über mehr Leistungsverbesserungen nach. Die aktuelle Implementierung ist also effizienter? – Maddy

+1

würde ich * weniger * Leistungsoptimierungen in Betracht ziehen. Verarbeiten Sie die Datei Zeile für Zeile und vergessen Sie das Chunking und parallele Streaming. Es scheint mir, dass ich Ihre letzte Frage bereits beantwortet habe. Ich habe es sicherlich versucht. – EJP

Antwort

1

RandomAccessFile macht nur Sinn, wenn Sie vorhaben, "herumspringen" innerhalb der Datei und Ihre Beschreibung von dem, was Sie tun, klingt nicht so. NIO macht Sinn, wenn Sie mit viel paralleler Kommunikation fertig werden müssen und nicht-blockierende Operationen, z. auf Steckdosen. Das scheint auch nicht dein Anwendungsfall zu sein.

Also mein Vorschlag ist es, mit dem einfachen Ansatz der Verwendung eines BufferedReader auf einem InputStreamReader (FileInputStream) zu bleiben (verwenden Sie nicht FileReader, da Sie nicht den Zeichensatz/die Codierung verwendet werden können) und Gehen Sie die Daten durch, wie Sie in Ihrem Beispielcode gezeigt haben. Lass den ParallelStream weg, nur wenn du schlechte Leistung siehst, kannst du das ausprobieren.

Immer daran denken: Vorzeitige Optimierung ist die Wurzel allen Übels.

+0

Ich schlage vor, dass Sie das gesamte Zitat nachschlagen. Du könntest eine Überraschung bekommen. – EJP

+1

@EJP "Programmierer verschwenden enorme Zeit damit, über die Geschwindigkeit unkritischer Teile ihrer Programme nachzudenken oder sich Gedanken darüber zu machen, und diese Effizienzversuche wirken sich stark negativ auf die Fehlersuche und Wartung aus sagen wir etwa 97% der Zeit: vorzeitige Optimierung ist die Wurzel allen Übels. Aber wir sollten unsere Chancen in diesen kritischen 3% nicht verpassen. " Ich sehe hier keine Überraschungen, zumindest bezweifle ich, dass diese Frage in die erwähnten 3% fällt. – Lothar

-1

Die offensichtliche Java 7 Lösung ist:

String lines = Files.readAllLines(Paths.get("file"), StandardCharsets.UTF_8).reduce((a,b)->a+b); 

Ehrlich gesagt habe ich keine Ahnung, ob es schneller ist, aber ich gues unter der Haube es liest es nicht in einen Puffer so zumindest in der Theorie sollte es schneller sein

+0

Sie haben falsch geraten. Siehe [Javadoc] (https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAllLines-java.nio.file.Path-). – EJP