12
votes

Un moyen le plus efficace de convertir introuvable en octets []?

long t1 = System.nanoTime();
byte[] bytes;
try {
    bytes = sun.misc.IOUtils.readFully(responseStream, -1, true);
} catch (Exception e) {
    return internalServerError();
}

long t2 = System.nanoTime();
System.out.println(t2 - t1);

6 commentaires

Hey Matt, j'ai lu à travers ce post. Je cherche une efficacité maximale.


Si vous êtes en préoccupé, vous devez mesurer et comparer différentes implémentations vous-même. Cependant, depuis que vous avez dit "il semble courir assez vite" Cela ne Sound Comme un goulot d'étranglement, si vous essayez de faire fonctionner votre code plus rapidement.


Jetez un coup d'œil à ce Stackoverflow. com / questions / 6649100 / ...


@Atiagoalmereida n'est pas vraiment pertinent ici.


@Mattball Le code n'a pas encore été déployé à la production, mais puisque ce code est appelé sur chaque charge de page, je souhaite que cela fonctionne aussi vite que possible pour maintenir le temps de chargement de la page.


sun.misc.ioutils.railly () n'accepte pas -1 comme une longueur, comme d'adoptopenjdk 8U242 au moins.


3 Réponses :


14
votes

oui. Utilisez un byteArrayOutPutStream plutôt que d'une arracheListe. Ensuite, lisez des morceaux d'octets à partir de l'intrustream (sans utiliser disponible () , qui devrait presque toujours jamais utiliser) et écrire ces morceaux sur le byearrayOutPutStream, jusqu'à la méthode Retourne -1. Ensuite, appelez TOBYNeArray () sur votre byTeArrayOutPutStream .

Vous pouvez utiliser Guava's byTestreams.tobyteArray () méthode, qui fait tout cela pour vous, ou si vous pouviez lire son code source pour avoir une meilleure idée de Comment ça fait? Lecture du Tutoriel IO pourrait également aider.


5 commentaires

Merci, laissez-moi tester cela. Je vais faire des tests de référence aussi


Disponible () renvoie le nombre d'octets pouvant être lu sans blocage. Il pourrait toujours retourner 0 (et cela fait par défaut).


Voir des améliorations de vitesse, merci


Une idée de savoir pourquoi sun.misc.ioutils.rafly serait exécuté deux fois plus vite que toutes les autres méthodes?


ByteArrayOutputStream.tobyteArray () crée une nouvelle copie des données inutiles. Y a-t-il un moyen d'éviter cela?



1
votes

pourquoi? Ce code est totalement équivalent à Lecture (octet []) Sauf si elle effectue deux étapes de copie supplémentaires sur l'ensemble des données. Vous n'avez pas besoin de cela. Un simple lu (octet []) serait plusieurs fois plus rapide.

L'utilisation de disponible () n'est pas valide aussi. Vous avez besoin de la réponse complète, pas seulement la partie qui peut être lue sans blocage. Vous devez faire boucle.


3 commentaires

Merci, je fais ces corrections maintenant. Je montrerai le diff dans quelques minutes.


Une lecture simple () ne garantit pas (à moins que cette implémentation de ChannelBufferInPutStream apporte cette garantie) que tout le flux est lu. Peut-être que ce n'est pas ce que vous vouliez vraiment dire, mais vous avez besoin d'une boucle de lecture jusqu'à ce que -1 soit retourné.


@Jbnizet est convenu, clarifié.



4
votes

Quel est le problème avec Apache Commons Io IOUTILS.TOBYTEARRAY Méthode? Cela a été optimisé sur plusieurs années à cet effet.


10 commentaires

Hé, je ne voulais pas importer une bibliothèque pour une seule fonction.


Eh bien, il y a de fortes chances que vous utiliseriez plus de fonctions dans cette bibliothèque au fil du temps et quel est le mal? Quoi qu'il en soit, c'est une source ouverte. Lisez la source et voyez comment ils le font si vous ne voulez pas le tout.


Qu'en est-il d'utiliser sun.misc.ioutils ? Il est intégré à Java, mais j'ai entendu de ne pas faire confiance aux bibliothèques du Soleil. IOUTILS.LIMISSIBLIE (RESPONSAIREME, -1, VRAI); Cela me donne des résultats plus rapides cependant. Peut-être que je vais donner et utiliser Apache Commons ...


J'ai mis à jour mon test de référence. On dirait que Sun.Misc.ioutils est la plus rapide sur ma machine, mais comme je l'ai dit avant d'avoir entendu que les bibliothèques de Sun ne sont pas dignes de confiance.


C'est juste une ancienne copie de l'Apache un, Afaik. Et ce ne sera pas nécessairement là si vous courez jamais sur l'IBM JVM.


Merci pour l'info :)


C'est assez étrange. J'ai fait un test de référence plus complet et sun.misc.ioutils.rafly fonctionne deux fois plus vite que toutes les autres méthodes.


Je ne pense pas que l'on veut importer une bibliothèque entière pour une seule fonction. Dans mon cas, cela aurait été un effort énorme pour le faire (redémarrage de serveurs et autres).


@sissonb Pourriez-vous sauvegarder votre affirmation selon laquelle les bibliothèques de Suns ne doivent pas faire confiance à une raison, de référence ou de citation? Vous avez peut-être raison, mais sans preuve, il s'agit d'une déclaration plutôt inutile.


C'est l'avertissement sur la bibliothèque. Avertissement: IOUTILS est une API exclusive interne et peut être supprimée dans une version future