Warum ist Java-Traversal langsamer als Datei readline?

9

Ich hatte dieses Stück Code:

%Vor%

Wie Sie im obigen Code sehen können, lese ich für jede Zeile in der Eingabedatei eine Zeile, führe einen Algorithmus aus, der diese Zeile grundlegend ändert, und schreibt dann die Ausgabezeile in eine Datei.

Es gibt 9k Zeilen in der Datei, und das gesamte Programm dauerte 3 Minuten auf meinem Rechner.

Ich dachte, okay, ich mache 2 I / Os für jeden (Zeilen-) Lauf des Algorithmus. Also mache ich rund 18k I / Os. Warum sammeln Sie nicht alle Zeilen zuerst in ein ArrayList , durchlaufen dann die Liste und führen den Algorithmus in jeder Zeile aus? Sammeln Sie außerdem jede Ausgabe in eine String-Variable und schreiben Sie dann alle Ausgaben einmal am Ende des Programms aus.

Auf diese Weise hätte ich insgesamt zwei große I / Os für das gesamte Programm (18k kleine Datei-I / Os zu zwei großen Datei-I / Os). Ich dachte, das wäre schneller, also schrieb ich folgendes:

%Vor%

Aber diese Sache dauerte 7 Minuten !!!

Warum ist das Schleifen durch ArrayList langsamer als das zeilenweise Lesen einer Datei?

Hinweis: Das Sammeln aller Zeilen durch readLine () und das Schreiben des bigOutput dauern jeweils nur wenige Sekunden. Es wurde auch keine Änderung an SomeAlgorithm () vorgenommen. Also, definitiv, ich denke der Schuldige ist for (String line: lines)

Update: Wie in den verschiedenen Kommentaren unten erwähnt, war das Problem nicht mit der ArrayList-Traversierung, sondern mit der Art, wie die Ausgabe mit + = akkumuliert wurde. Das Wechseln zu StringBuilder () ergab ein schnelleres Ergebnis als das Original.

    
sanjeev mk 10.08.2014, 18:32
quelle

2 Antworten

3

Ich vermute, dass der Leistungsunterschied darauf zurückzuführen ist, wie Sie die Ausgabe in einer Variablen erfassen ( bigOutput ). Meine Vermutung ist, dass dies viele Speicher-Neuzuweisungen und das Kopieren von Zeichendaten beinhaltet, was die wahre Ursache für die Langsamkeit ist.

    
NPE 10.08.2014 18:35
quelle
1

Das hängt von der Größe der Datei ab, aber wahrscheinlich geht es hier darum, dass es länger dauert, die ArrayList -Speicherung und die Verkettung von Zeichenfolgen zu ändern, als dies bei vielen kleinen Dateioperationen der Fall ist.

Beachten Sie, dass die Festplatte und das Betriebssystem beide eine gewisse E / A-Cachespeicherung durchführen, und einige davon beinhalten Vorauslesen (mit der Erwartung, dass Sie wahrscheinlich Daten sequenziell lesen), so dass der erste Lesevorgang wahrscheinlich ist stopfen einen Teil der Datei in den I / O-Cache, von dem Sie sehr schnell lesen können.

Sie handeln daher kleine Lesevorgänge aus dem I / O-Cache für viele Größen von flachen Arrays ( ArrayList und Ausgabe-Stachel), die jedes Mal langsamer und langsamer werden.

tl; dr-Version: Lassen Sie die verschiedenen I / O-Caches ihre Arbeit machen.

    
cdhowie 10.08.2014 18:37
quelle

Tags und Links