Ich lese eine 50G-Datei, die Millionen von Zeilen enthält, die durch Zeilenumbruchzeichen getrennt sind. Derzeit verwende ich folgende Syntax, um die Datei
zu lesen %Vor%Da die Datei zu groß ist, dauert es 2 Stunden, um die gesamte Datei zu verarbeiten. Kann ich das Lesen der Datei von der Festplatte verbessern, so dass die IO (Reading) -Operation minimal Zeit benötigt. Die Einschränkung mit meinem Code ist, dass ich jede Zeilenreihenfolge bearbeiten muss.
es dauert 2 Stunden, um die ganze Datei zu verarbeiten.
50 GB / 2 Stunden entsprechen ungefähr 7 MB / s. Es ist überhaupt keine schlechte Rate. Eine gute (moderne) Festplatte sollte in der Lage sein, eine höhere Rate kontinuierlich aufrechtzuerhalten, also ist Ihr Engpass möglicherweise nicht die I / O? Sie verwenden bereits den BufferedReader, der, wie der Name schon sagt, im Speicher zwischenspeichert, was er liest. Sie könnten experimentieren, indem Sie den Reader mit einem etwas größeren Puffer als die Standardgröße (8192 Byte) erstellen, wie folgt:
%Vor%Beachten Sie, dass der BufferedReader mit dem Standardpuffer von 8192 Byte und dem Durchsatz von 7 MB / s seinen Puffer fast 1000 Mal pro Sekunde füllt, sodass eine Verringerung dieser Zahl wirklich helfen könnte, den Overhead zu reduzieren. Aber wenn die Verarbeitung, die Sie statt der E / A durchführen, der Engpass ist, dann wird Ihnen kein I / O-Trick mehr helfen. Sie sollten es vielleicht in Betracht ziehen, es multi-threaded zu machen, aber ob es machbar ist und wie, hängt davon ab, was "Verarbeitung" hier bedeutet.
Ihre einzige Hoffnung ist es, das Lesen und Verarbeiten dessen, was drin ist, parallel zu machen. Ihre Strategie sollte sein, niemals den gesamten Dateiinhalt auf einmal im Speicher zu haben.
Beginnen Sie mit dem Profiling des Codes, den Sie sehen müssen, wo die Zeit verbracht wird. Schreiben Sie den Teil, der am meisten Zeit benötigt, neu und profilieren Sie ihn, um zu sehen, ob er verbessert wurde. Wiederholen Sie das so lange, bis Sie ein akzeptables Ergebnis erhalten.
Ich würde über Hadoop und eine verteilte Lösung nachdenken. Datensätze, die größer sind als Ihre, werden jetzt routinemäßig verarbeitet. Sie müssen vielleicht ein bisschen kreativer in Ihrem Denken sein.
Ohne NIO können Sie die Durchsatzbarriere nicht durchbrechen. Verwenden Sie beispielsweise new Scanner(File)
, anstatt direkt Leser zu erstellen. Kürzlich habe ich mir diesen Quellcode angeschaut, er benutzt NIOs Dateikanäle.
Aber das erste, was ich vorschlagen würde ist, eine leere Schleife mit BufferedReader
zu starten, die nichts als Lesen tut. Beachten Sie den Durchsatz - und achten Sie auch auf die CPU. Wenn die CPU in der Schleife liegt, dann gibt es definitiv ein Problem mit dem IO-Code.
Deaktivieren Sie das Antivirenprogramm und alle anderen Programme, die beim Lesen der Datei zu Datenträgerkonflikten führen.
Defragmentieren Sie die Festplatte.
Erstellen Sie eine unformatierte Festplattenpartition und lesen Sie die Datei von dort.
Lesen Sie die Datei von einer SSD.
Erstellen Sie eine 50-GB-Ramdisk und lesen Sie die Datei von dort.
Ich denke, dass Sie die besten Ergebnisse erzielen können, wenn Sie das Problem, das Sie lösen möchten, erneut betrachten. Es gibt eindeutig einen Grund Sie laden diese 50Gig-Datei. Überlegen Sie, ob es keinen besseren Weg gibt, die gespeicherten Daten zu durchbrechen und nur die Daten zu verwenden, die Sie wirklich benötigen.
Die Art, wie Sie die Datei lesen, ist in Ordnung. Es kann Wege geben, um es schneller zu bekommen, aber es erfordert in der Regel Verständnis, wo Ihr Engpass ist. Da der E / A-Durchsatz tatsächlich am unteren Ende liegt, gehe ich davon aus, dass die Berechnung einen Leistungsnebeneffekt hat. Wenn es nicht zu lang ist, können Sie das ganze Programm zeigen.
Alternativ können Sie Ihr Programm ohne den Inhalt der Schleife ausführen und sehen, wie lange es dauert, die Datei zu lesen:)
Tags und Links java file bufferedreader