java performance bufferedreader bufferedinputstream

java - ¿Por qué el rendimiento de BufferedReader es mucho peor que BufferedInputStream?



performance (2)

El BufferedReader ha convertido los bytes en caracteres. Este byte a byte que analiza y copia a un tipo más grande es costoso en comparación con una copia directa de bloques de datos.

byte[] bytes = new byte[150 * 1024 * 1024]; Arrays.fill(bytes, (byte) ''/n''); for (int i = 0; i < 10; i++) { long start = System.nanoTime(); StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)); long time = System.nanoTime() - start; System.out.printf("Time to decode %,d MB was %,d ms%n", bytes.length / 1024 / 1024, time / 1000000); }

huellas dactilares

Time to decode 150 MB was 226 ms Time to decode 150 MB was 167 ms

NOTA: tener que hacer esto entremezclado con las llamadas al sistema puede ralentizar ambas operaciones (ya que las llamadas al sistema pueden perturbar el caché)

Entiendo que el uso de un BufferedReader (ajuste de un FileReader) va a ser significativamente más lento que el uso de un BufferedInputStream (ajuste de un FileInputStream), porque los bytes en bruto tienen que convertirse en caracteres. ¡Pero no entiendo por qué es mucho más lento! Aquí están los dos ejemplos de código que estoy usando:

BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(filename)); try { byte[] byteBuffer = new byte[bufferSize]; int numberOfBytes; do { numberOfBytes = inputStream.read(byteBuffer, 0, bufferSize); } while (numberOfBytes >= 0); } finally { inputStream.close(); }

y:

BufferedReader reader = new BufferedReader(new FileReader(filename), bufferSize); try { char[] charBuffer = new char[bufferSize]; int numberOfChars; do { numberOfChars = reader.read(charBuffer, 0, bufferSize); } while (numberOfChars >= 0); } finally { reader.close(); }

He intentado pruebas utilizando varios tamaños de búfer, todos con un archivo de 150 megabytes. Aquí están los resultados (el tamaño del búfer está en bytes; los tiempos están en milisegundos):

Buffer Input Size Stream Reader 4,096 145 497 8,192 125 465 16,384 95 515 32,768 74 506 65,536 64 531

Como puede verse, el tiempo más rápido para el BufferedInputStream (64 ms) es siete veces más rápido que el tiempo más rápido para el BufferedReader (465 ms). Como dije anteriormente, no tengo un problema con una diferencia significativa; Pero esta gran diferencia parece irrazonable.

Mi pregunta es: ¿alguien tiene alguna sugerencia sobre cómo mejorar el rendimiento del BufferedReader o un mecanismo alternativo?


en la implementación de BufferedReader hay una constante fija defaultExpectedLineLength = 80 , que se usa en el método readLine al asignar StringBuffer . Si tiene un archivo grande con muchas líneas más largas que 80, este fragmento podría ser algo que se pueda mejorar.

if (s == null) s = new StringBuffer(defaultExpectedLineLength); s.append(cb, startChar, i - startChar);