1Danke
ERLEDIGT
JA
JA
ANTWORTEN
3
3
ZUGRIFFE
476
476
EMPFEHLEN
-
Hallo zusammen.
Momentan muss ich Log-Dateien parsen, es handelt sich dabei um große Text-Dateien mit mindestens mehreren hundert MB (mein Testfile ist ~400MB). Da ich jede Zeile einzeln brauche, hat sich der java.io.BufferedReader angeboten, der mir bequemerweise bereits eine readLine() Methode liefert.
Das Problem ist jetzt, dass das Einlesen der Datei viel zu lang dauert. Ich habe alle Operationen auf die eingelesenen Zeilen auskommentiert, um wirklich die reine Lesedauer zu erhalten. Die Messung sieht folgendermaßen aus:
Diese Messung ergibt ca. 1ms/Zeile Verarbeitungszeit. Was auch zutrifft, wenn ich ein kleines Testfile benutze oder den Puffer des Readers höhersetze (Maximum waren 10k bisher).Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
FileReader fr = new FileReader(file); br = new BufferedReader(fr); String line = null; long lineCounter = 0; long ts1 = System.currentTimeMillis(); while((line = br.readLine()) != null){ // hier kämen Aufrufe zum Verarbeiten der Zeile lineCounter++; if(lineCounter % 1000 == 0){ long ts2 = System.currentTimeMillis(); System.out.println(lineCounter + " (" + (ts2 - ts1) + "ms)"); ts1 = ts2; } Thread.sleep(1); }
Meine bisherigen Überlegungen/Ansätze/Tests:- An mangelnden System-Resourcen/hohem Garbage-Collecting kann es kaum liegen, da stets zwischen 1 und 2 GB RAM zur Verfügung standen, sowie 90% CPU (2x2.3GHz). Der Javaw-Prozess hat auch nie mehr 10 - 12 KB RAM in Anspruch genommen.
- Andere Streams zu verschachteln (FileInputStream => BufferedInputStream => InputStreamReader => BufferedReader) hat keinen Unterschied gemacht
- RandomAccessFile#readLine() dauert ebenfalls gleich lang
- Mit einer Puffergröße von 10k komme ich beim byte-weisen Einlesen auf 0.0068ms/Zeile. Das ist jedoch hinfällig, wenn die Daten programmatisch wieder nach CR/LF o.Ä. durchsucht und gesplitted werden müssen (ebenfalls 1ms/Zeile).
- Ein Kollege hat eine kleine (und schlampige) Test-Routine in C# geschrieben, mit einem BufferedReader-Äquivalent und kam (inkl. kleiner Stringverarbeitung) auf 0.038ms/Zeile, was immerhin um einen Faktor 25+ schneller ist als mein Auslesen.
Ich hoffe sehr, dass Java in Sachen Character-Verarbeitung nicht einfach nur langsam ist und einer von euch mir weiterhelfen kann. Mein guter Freund Google sagt mir seit gestern, dass es (außer Frameworks von Apache z.B.) keine besseren Ansätze gibt zum zeilenweisen Auslesen als den BufferedReader.
Grüße
miffiGeändert von miffi (30.11.11 um 13:13 Uhr)
"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Douglas Adams
-
30.11.11 14:28 #2
Hi,
also ich habe auch die Zeit vom BufferedReader gestoppt und komme auf weniger.
Ersteinmal meine PC-Daten:
CPU: Intel Core 2 Duo 2,80 GHz
RAM: 2GB
Ich komme bei einem Textdatei mit einer Größe von 445MB auf eine Lesegeschwindigkeit von 0,0027 ms/Line. Die Textdatei enthält 5millionen Zeilen. Für die gesamte Textdatei benötige ich eine Zeit von 13500ms oder anders 13,5sec.
Hier mein Code mit dem ich getestet habe.
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/** * @param args */ public static void main(String[] args) { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("./Tests/bigfile.txt")))); String line; StopWatch sw = new StopWatch(); sw.start(); int lineCounter = 0; while((line = reader.readLine()) != null) { lineCounter++; } sw.stop(); System.out.println("NeededTime=" + sw.getTime() + ", Lines="+lineCounter+", ms/Line="+((double)sw.getTime()/(double)lineCounter)); } catch(FileNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(reader); } }
Du solltest bei deinem Code darauf achten, bei einer Zeitmessung kein Thread.sleep(...) einzubauen. Das ist dann klar, dass wen du den Thread für 1msec schlafen legst, dass er dann pro Zeile ca. 1msec braucht.
Außerdem verlangsamt eine Ausgabe die Zeitmessung zusätzlich, genauso wie sonstige Berechnung, Bedingungen, etc.
Gruß
FabioBitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
-
Hi Fabio, danke für die schnelle Antwort!
Der sleep()-call war ein Relikt aus einer anderer Schleife, die ich an dieser Stelle hatte. Und vor lauter Betriebsblindheit hab ich es total übersehen...
Ich geh jetzt in 6.7s über 6.2 Mio Zeilen Text, von daher ist alles in Ordnung. Weißt, da programmiert man seit Jahren professionell, und dann passiert einem so ein Erstsemester-Kram xD
Wär ja direkt lustig, wenn nicht 8 wichtige Arbeitsstunden für die Forschung nach Alternativen draufgegangen wären...
Danke dir und Gruß
miffi"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Douglas Adams
-
30.11.11 15:02 #4
Keine Ursache. Oft hilft auch gelegentlich eine kurze Pause von 5 Minuten, um seine Blindheit zu überwinden.

Aber ich kenn das auch, die kleinsten Fehler sucht man prinzipell immer am längsten.
Gruß
FabioBitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]
Tutorials:
Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
JAnimationPanel - Animationen für Swing/AWT
SWTRatingBar (Bewertungs-Composite) selbst programmieren
____________________________________________________________________________
Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.
Ähnliche Themen
-
BufferedReader
Von mal2000b im Forum JavaAntworten: 2Letzter Beitrag: 05.02.10, 20:59 -
BufferedReader Limit?
Von Conners im Forum JavaAntworten: 2Letzter Beitrag: 22.10.08, 09:07 -
BufferedReader
Von steffias im Forum Java GrundlagenAntworten: 2Letzter Beitrag: 04.05.08, 22:17 -
BufferedReader
Von Kenbu im Forum Swing, Java2D/3D, SWT, JFaceAntworten: 2Letzter Beitrag: 22.08.07, 16:59 -
Label / Emblem um einen Flaschenhals wickeln...
Von tobsnn im Forum Cinema 4DAntworten: 9Letzter Beitrag: 17.02.05, 16:11





Zitieren
Login





