2010-10-27 9 views
6

Ich möchte lesen Sie einen großen InputStream und geben Sie es als String zurück. Dieser InputStream ist ein großer. Normalerweise benötigt es viel Zeit und viel Speicher, während es ausgeführt wird. Der folgende Code ist der, den ich bisher entwickelt habe. Ich muss diesen Code konvertieren, da es die Arbeit in einem geringeren zeitaufwendigen geringeren Speicher erledigt.Tuning der Leistung beim Lesen eines großen InputStream in Java

Können Sie mir eine Idee, dies zu tun.

BufferedReader br = 
    new BufferedReader(
     new InputStreamReader(
      connection.getInputStream(), 
      "UTF-8") 
     ); 

StringBuilder response = new StringBuilder(1000); 

char[] buffer = new char[4096]; 

int n = 0; 
while(n >= 0){ 
    n = br.read(buffer, 0, buffer.length); 
    if(n > 0){ 
     response.append(buffer, 0, n); 
    } 
} 
return response.toString(); 

Vielen Dank!

+2

, was eine „Menge“ der Erinnerung ist. Es ist unvermeidlich, dass Sie genug Speicher benötigen, um den gesamten String, den Sie bauen, zu halten. Siehst du etwas dramatisch schlechter als erwartet? – djna

+0

was liest du? – dogbane

+0

Ja. es stimmt, dass der verbrauchte Speicher proportional zur Größe der Antwort (String) ist. Aber hier geht es darum, den Speicher effektiv zu nutzen (Reduzierung der unnötigen Speicherauslastung, etc.). Für ein Beispiel hier habe ich den StringBuilder verwendet, anstatt die Eingabe mit + 's (wie str = str + newStr) an eine selbe Zeichenkette anzuhängen, um die unnötige Speicherauslastung zu reduzieren. So erwartete ich weitere Ideen, um meinen Code viel besser zu machen, indem ich das Gedächtnis verwalte und den Code beschleunige. – Namalak

Antwort

3

Wenn Sie gepufferte E/A ausführen, können Sie nur ein Zeichen vom gepufferten Leser lesen. Dann baue die Zeichenfolge auf und führe am Ende eine toString() -Methode aus.

+0

Ist das nicht das Lesen von Zeichen, während sie in einem char Array zu speichern ist besser als das Lesen jedes Char und BuildUp die Zeichenfolge? Ich meine lese() Vs lesen (char [], int Start, int Ende) – Namalak

+1

Das ist, was der gepufferte Leser unter die Abdeckungen tut .... Versuchen Sie, die Quelle von BufferedReader zu betrachten. –

1

Sie können feststellen, dass für große Dateien auf einigen Betriebssystemen mmap die Datei über FileChannel.map wird Ihnen bessere Leistung geben - die Datei zuordnen und dann eine Zeichenfolge aus dem zugeordneten ByteBuffer erstellen. Sie müssen jedoch einen Benchmark erstellen, da es in manchen Fällen schneller sein kann, dass die 'traditionelle' IO schneller ist.

+0

OP liest eine URL, keine Datei. – dogbane

+0

Ja. Ich bin neu in dieser FileChannel.map. Kann dies mit dem OP verwendet werden, liest eine URL – Namalak

+0

@dogbane und Namalak: Um fair zu sein, das wurde nicht klar gemacht, bis ich meine Antwort verließ :) Ich werde dies hier für den Fall, dass jemand später kommt und will das tun Gleiches für eine Datei. –

0

Kennen Sie die maximale Länge Ihrer Saite im Voraus? Sie geben derzeit eine Anfangskapazität von 1000 für Ihren Puffer an. Wenn das, was Sie lesen, viel größer ist als Sie, werden Sie einige Kosten bei der Zuweisung von größeren internen Puffern zahlen.

Wenn Sie die Kontrolle über den Lebenszyklus von dem haben, was Sie gerade lesen, könnten Sie vielleicht ein einzelnes wiederverwendbares Byte-Array als Puffer reservieren. Daher Vermeidung von Garbage Collection.

0

die Größe des Puffers erhöhen. Je größer der Puffer, desto schneller können alle Daten gelesen werden. Wenn Sie wissen (oder wissen, wie viele Bytes im Stream verfügbar sind), können Sie sogar einen Puffer der gleichen Größe im Voraus zuweisen.

+0

Danke. 1000 ist bis jetzt gut. Unnötiger Anstieg der Puffergröße ist auch ineffizient, oder? – Namalak

+0

Ich meinte den Zeichenpuffer, den Sie auf 4096 gesetzt haben. – dogbane

0

Sie könnten den Code in einem separaten Thread ausführen ... es wird nicht schneller ausgeführt, aber zumindest wird Ihr Programm in der Lage sein, etwas anderes zu tun, anstatt auf Daten aus dem Stream zu warten.

+0

Aber es gibt keine parallel ausführbaren Arbeiten. – Namalak