web-dev-qa-db-fra.com

Convert ASCII Octet [] en chaîne

J'essaie de passer un octet [] contenant ASCII caractères à log4J, pour être connecté à un fichier à l'aide de la représentation évidente. Quand je passe simplement dans le BYT [], il est bien sûr traité comme Un objet et les journaux sont assez inutiles. Lorsque j'essaie de les convertir en chaînes en utilisant new String(byte[] data), la performance de mon application est divisée par deux.

Comment puis-je les transmettre efficacement, sans engager une pénalité de temps environ 30us de la convertir en cordes.

En outre, pourquoi faut-il si longtemps pour les convertir?

Merci.

éditer

Je devrais ajouter que je suis optmise pour la latence ici - et oui, 30US fait la différence! De plus, ces matrices varient d'environ 100 jusqu'à quelques milliers d'octets.

19
jwoolard

Ce que vous voulez faire est de retarder le traitement du tableau des octets [] jusqu'à ce que Log4j décide qu'il souhaite réellement enregistrer le message. De cette façon, vous pouvez le connecter au niveau de débogage, par exemple, tout en testant, puis désactivez-le pendant la production. Par exemple, vous pourriez:

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

Maintenant, vous ne payez pas la pénalité de vitesse à moins que vous ne connaissiez réellement les données, car la méthode de totring n'est pas appelée avant que Log4j décide que cela vous connectera réellement le message!

Maintenant, je ne suis pas sûr de ce que vous entendez par "la représentation évidente", donc j'ai supposé que vous voulez dire que vous voulez convertir une chaîne en réinterprétant les octets comme le codage du caractère par défaut. Maintenant, si vous avez affaire à des données binaires, cela ne vaut évidemment rien. Dans ce cas, je suggérerais d'utiliser Arrays.tostring (octet []) pour créer une chaîne formatée le long des lignes de

[54, 23, 65, ...]
14
Steven Schlansker

si vos données sont en fait ASCII (données à 7 bits), alors vous devriez utiliser new String(data, "US-ASCII") Au lieu de dépendre de l'encodage par défaut de la plate-forme. Cela peut être plus rapide que d'essayer de l'interpréter comme codage par défaut de la plate-forme (qui pourrait être UTF-8, qui nécessite plus d'introspection).

Vous pouvez également accélérer cela en évitant la recherche de charset touchée à chaque fois, en mettant en cache le Charset instance et appelant new String(data, charset) .

Cela dit: ça fait très longtemps que j'ai vu real ASCII données dans l'environnement de production

8
Joachim Sauer
1
Rubens Farias

Performance de moitié? Quelle est la taille de ce tableau d'octets? Si c'est par exemple 1 Mo, il y a certainement plus de facteurs à prendre en compte que de simplement "convertir" des octets en caractères (qui est supposé être assez rapide). écrire 1 Mo de données au lieu de "Just" 100bytes (que la fonction byte[].toString() peut générer) à un fichier journal va évidemment prendre un certain temps. Le système de fichiers de disque n'est pas aussi rapide que RAM Memory.

Vous devrez modifier la représentation des chaînes de la matrice d'octets. Peut-être avec des informations plus sensibles, par exemple Le nom associé à celui-ci (nom de fichier?), sa longueur et ainsi de suite. Après tout, qu'est-ce que ce réseau d'octet en fait représente?

éditer: Je ne me souviens pas d'avoir vu le "environ 30us" phrase dans votre question, peut-être que vous l'avez modifiée dans Dans les 5 minutes qui suivent une demande, mais il s'agit en réalité de la microoptimisation et il ne devrait certainement pas causer de "performance de moitié" en général. Sauf si vous les écrivez un million de fois par seconde (alors alors, pourquoi voudriez-vous faire cela? N'a -blez-vous pas trop le phénomène "Logging"?).

1
BalusC