7
votes

Compression sur les tampons directs de Java Nio

Le flux d'entrée / sortie GZIP ne fonctionne pas sur des tampons directs Java.

Y a-t-il une implémentation d'algorithme de compression qui fonctionne directement sur des tampons directs?

De cette façon, il n'y aurait pas de frais généraux de copier un tampon direct vers un tableau d'octets Java pour la compression.


10 commentaires

La compression sans frais généraux est impossible. Les tampons directs sont, par définition, "un conteneur pour une quantité fixe de données d'un type primitif spécifique" . Une transformation une telle compression ou cryptage doit être effectuée en dehors du tampon.


je comprend. Je veux juste faire la compression sans la pénalité supplémentaire de la première copie de l'ensemble du tableau de tampon direct à une matrice d'octet Java


GzipInputStream ne crée pas de copie - il diffuse tout de suite du fichier (basé sur la vérification de la source). J'imagine donc que c'est probablement plus rapide que de créer votre propre tampon direct et de mapper un fichier. Si vous voulez vraiment utiliser un tampon direct, vous pouvez écrire votre propre intrigue qui diffère de votre tampon ...


La compression GZIP est tellement plus lente que de copier les données qu'il est peu probable pour faire beaucoup de différence.


Russell: Mon tampon direct n'est pas créé à partir d'un fichier. Je le crée mon code pour éviter GC


Malheureusement, les mecs de JDK Team n'ont pas ajouté tampon direct à l'Inflater / Deflater, peu de lignes de code et de verrouillage / copie de l'octet []. Hélas. JISEZ JZLIB, il peut être modifié (ne peut pas poster la version modifiée entière) pour utiliser BYTEBUFFER au lieu d'octets [].


@Russellzahniser, IT Crée une copie à charger à partir du fichier, le GZipstream par défaut utilise 512 octets de tampon pour lire de petits mandrins et passer au code natif. Utiliser un tampon mappé et passer directement au zlib natif serait meilleur.


@Peter, techniquement, vous pouvez spécifier le niveau de compression et les bits maximum. L'allocation de mémoire / distribution due à des bits hautes max (15) et le niveau de mémoire (8 sur 9) ne peut pas aider avec de petits morceaux de compression. Réduire cela et réutiliser le défileur améliore considérablement la vitesse des petites pièces et apporte le niveau de compression 2x. il n'est pas si mauvais (sûrement je n'utilise pas la gzip ordinaire si)


Dans le passé, lorsque j'ai voulu une compression raisonnable efficace et sur de petits messages, j'ai écrit ma propre stratégie. Compte tenu du déflorateur doit apprendre une durée d'apprentissage, la connaissance du format de données peut donner des résultats aussi bons ou meilleurs.


Peut-être que vous pourriez décrire le format des données que vous souhaitez compresser avec des exemples et nous pourrions discuter de la manière de la compresser le plus efficacement (peut-être dans une autre question)


3 Réponses :


0
votes

Si vous utilisez BYTEBUFFERSERS, vous pouvez utiliser quelques emballages d'entrée / de sortie simples tels que ceux-ci: xxx

test: xxx


3 commentaires

Même en enveloppant le bytebuffer dans un flux ne vous aide pas, car il est copié en interne (parfois deux fois), Sorta vaincit le but de l'octebuffer


Désolé mais je ne l'obtiens pas, quand cette copie se produirait-elle? J'ai vérifié le code pour INTERPSTREAM, OUTPUTSTREAM et même les classes GZIP et ne peut trouver aucune copie.


C'est comme ça que cela fonctionne, vérifiez GonflingInputStream et que le Native IPL doit copier (ou code PIN dépend de la JVM / GC) l'octet [] pour le transmettre au zlib



2
votes

Je ne veux pas nuire à votre question, mais est-ce vraiment un bon point d'optimisation dans votre programme? Avez-vous vérifié avec un profileur que vous avez en effet un problème? Votre question telle que indiquée implique que vous n'ayez effectué aucune recherche, mais vous devinez simplement que vous aurez un problème de performance ou de mémoire en allouant un octet []. Étant donné que toutes les réponses de ce fil sont susceptibles d'être des hacks de quelque sorte, vous devriez vraiment vérifier que vous réellement avez un problème avant de le résoudre.

retour à la question, si vous voulez Pour comprimer les données "en place" sur un bytebuffer, la réponse est non, il n'y a pas de capacité à le faire intégré à Java.

Si vous avez alloué votre tampon comme ce qui suit: < Pré> xxx

Vous pouvez filtrer votre octet [] via un bytebufferInputStream comme la réponse précédente suggérée.


3 commentaires

J'accepte cela comme réponse, mais j'attends toujours un qui fournit une solution, disons sous la forme d'une bibliothèque qui fonctionne à l'aide de JNI sur des tampons d'octets.


J'étais curieux de ce question parce que je voulais trouver un moyen de convertir un dossier en un fichier zip en nom uniquement en place pour une suppression rapide des grands dossiers.


Éviter la copie des données est presque toujours un coup de pouce important pour la performance. Cependant, les données déjà dans un tampon direct ne peuvent pas être comprimées sans être copiées à moins que le système d'exploitation lui-même.