java - read - ¿Es excesivo usar BufferedWriter y BufferedOutputStream juntos?
read string from java socket (3)
El BufferedWriter almacenará en búfer la entrada en el outputStreamWriter, que se recomienda porque evita que el escritor inicie el codificador para cada carácter.
Recomendado por quién y en qué contexto? ¿Qué quiere decir con "poner en marcha el codificador"? ¿Estás escribiendo un solo personaje a la vez para el escritor de todos modos? (No sabemos mucho sobre cómo está usando el escritor ... eso podría ser importante).
BufferedOutputStream almacenaría los bytes del Escritor para evitar poner potencialmente un byte a la vez en la red.
¿Qué te hace pensar que escribiría un byte a la vez? Creo que es muy poco probable que OutputStreamWriter
escriba un byte a la vez en el escritor subyacente, a menos que realmente escriba un carácter a la vez.
Además, espero que la transmisión de salida de red use algo como el algoritmo de Nagle para evitar el envío de paquetes de un solo byte.
Como siempre, con la optimización, debe hacerlo en función de la evidencia ... ¿ha realizado alguna prueba con y sin estas capas de almacenamiento en búfer?
EDITAR: Solo para aclarar, no estoy diciendo que las clases de buffering sean inútiles. En algunos casos, son absolutamente el camino correcto a seguir. Solo digo que, como con todas las optimizaciones, no deberían usarse a ciegas. Debe considerar para qué está tratando de optimizar (uso del procesador, uso de la memoria, uso de la red, etc.) y medir. Hay muchos factores que importan aquí, y no menos importante es el patrón de escritura. Si ya está escribiendo "groseramente" escribiendo grandes bloques de datos de caracteres, entonces los búferes tendrán un impacto relativamente pequeño. Si en realidad estás escribiendo un solo personaje a la vez para el escritor, entonces serían más significativos.
Quiero escribir en un socket. Después de leer sobre la red IO, me parece que la forma óptima de escribir es hacer algo como esto:
OutputStream outs=null;
BufferedWriter out=null;
out =
new BufferedWriter(
new OutputStreamWriter(new BufferedOutputStream(outs),"UTF-8"));
El BufferedWriter
almacenará en búfer la entrada al OutputStreamWriter
que se recomienda, ya que evita que el escritor inicie el codificador para cada carácter.
BufferedOutputStream
almacenaría los bytes del Writer
para evitar poner potencialmente un byte a la vez en la red.
Parece un poco exagerado, pero parece que ayuda? Agradecido por cualquier ayuda ..
EDITAR: del javadoc en OutputStreamWriter
:
Cada invocación de un método write () provoca que el convertidor de codificación se invoque en los caracteres dados. Los bytes resultantes se acumulan en un búfer antes de escribirse en la secuencia de salida subyacente. El tamaño de este buffer puede ser especificado, pero por defecto es lo suficientemente grande para la mayoría de los propósitos. Tenga en cuenta que los caracteres pasados a los métodos write () no están almacenados en el búfer.
Para obtener la máxima eficiencia, considere envolver un OutputStreamWriter dentro de un BufferedWriter para evitar frecuentes invocaciones de convertidor. Por ejemplo:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
El objetivo de las clases Buffered * es unir las operaciones de escritura pequeñas en una más grande, reduciendo así la cantidad de llamadas al sistema y aumentando el rendimiento.
Dado que un BufferedWriter ya recopila escrituras en un búfer, luego convierte los caracteres en el búfer en otro búfer y escribe ese búfer en el OutputStream subyacente en una sola operación, el OutputStream ya se invoca con grandes operaciones de escritura. Por lo tanto, un BufferedOutputStream no encuentra nada que combinar, y es simplemente redundante.
Por otro lado, lo mismo puede aplicarse al BufferedWriter: el almacenamiento en búfer solo ayudará si el escritor solo pasa algunos caracteres a la vez. Si sabe que la persona que llama solo escribe cadenas enormes, BufferedWriter no encontrará nada que combinar y también redundará en redundancia.
Sí, es excesivo. Del Javadoc para OutputStreamWriter
: "Cada invocación de un método write () hace que el convertidor de codificación sea invocado en los caracteres dados. Los bytes resultantes se acumulan en un búfer antes de escribirse en el flujo de salida subyacente".