utf8 getbytes convertir conversion change array java log4j ascii bytearray

getbytes - java string unicode



Convertir byte ASCII[] a String (5)

Estoy intentando pasar un byte [] que contiene caracteres ASCII a log4j, para iniciar sesión en un archivo utilizando la representación obvia. Cuando simplemente paso el byt [], por supuesto, se trata como un objeto y los registros son bastante inútiles. Cuando trato de convertirlos a cadenas utilizando una new String(byte[] data) , el rendimiento de mi aplicación se reduce a la mitad.

¿Cómo puedo pasarlos de manera eficiente, sin incurrir en la penalización de aproximadamente 30us tiempos de convertirlos en cadenas?

Además, ¿por qué se tarda tanto en convertirlos?

Gracias.

Editar

Debo agregar que estoy optmising para la latencia aquí, y sí, ¡lo único que hacemos es una diferencia! Además, estas matrices varían desde ~ 100 hasta unos pocos miles de bytes.


¿Rendimiento a la mitad? ¿Qué tan grande es esta matriz de bytes? Si es, por ejemplo, 1 MB, entonces hay más factores a tener en cuenta que simplemente "convertir" de bytes a caracteres (lo que se supone que es lo suficientemente rápido). Escribir 1 MB de datos en lugar de "solo" 100 byte[].toString() puede generar el byte[].toString() ) en un archivo de registro obviamente llevará algo de tiempo. El sistema de archivos de disco no es tan rápido como la memoria RAM.

Tendrá que cambiar la representación de cadena de la matriz de bytes. Tal vez con información más confidencial, por ejemplo, el nombre asociado (nombre de archivo?), Su longitud, etc. Después de todo, ¿qué representa realmente esa matriz de bytes?

Edit : No recuerdo haber visto la frase "aproximadamente 30us" en su pregunta, tal vez la editó dentro de los 5 minutos posteriores a la pregunta, pero esto es en realidad una microoptimización y ciertamente no debería causar un "rendimiento reducido a la mitad" en general. A menos que los escriba un millón de veces por segundo (aún así, ¿por qué querría hacer eso? ¿No está abusando del fenómeno de "registro"?).


ASCII es una de las pocas codificaciones que se pueden convertir a / desde UTF16 sin búsquedas aritméticas o de tablas, por lo que es posible convertirlas manualmente:

String convert(byte[] data) { StringBuilder sb = new StringBuilder(data.length); for (int i = 0; i < data.length; ++ i) { if (data[i] < 0) throw new IllegalArgumentException(); sb.append((char) data[i]); } return sb.toString(); }

Pero asegúrate de que realmente sea ASCII, o terminarás con basura.



Lo que quiere hacer es retrasar el procesamiento de la matriz de bytes [] hasta que log4j decida que realmente quiere registrar el mensaje. De esta forma, podría registrarlo en el nivel DEBUG, por ejemplo, durante la prueba y luego desactivarlo durante la producción. Por ejemplo, usted podría:

final byte[] myArray = ...; Logger.getLogger(MyClass.class).debug(new Object() { @Override public String toString() { return new String(myArray); } });

Ahora no paga la penalización de velocidad a menos que realmente registre los datos, porque el método toString no se llama hasta que log4j decide que realmente registrará el mensaje.

Ahora no estoy seguro de lo que quieres decir con "la representación obvia", por lo que asumí que te refieres a convertir a una cadena reinterpretando los bytes como la codificación de caracteres predeterminada. Ahora bien, si está tratando con datos binarios, esto obviamente no vale nada. En ese caso, sugeriría usar Arrays.toString(byte[]) para crear una cadena formateada a lo largo de las líneas de

[54, 23, 65, ...]


Si sus datos son de hecho ASCII (es decir, datos de 7 bits), entonces debería usar una new String(data, "US-ASCII") lugar de depender de la codificación predeterminada de la plataforma. Esto puede ser más rápido que tratar de interpretarlo como la codificación predeterminada de su plataforma (que podría ser UTF-8, que requiere más introspección).

También puede acelerar esto evitando el golpe de Charset-Lookup cada vez, almacenando en caché la instancia de Charset y llamando a la new String(data, charset) .

Dicho esto: hace mucho, mucho tiempo que no veo datos ASCII reales en el entorno de producción