Zstd: Meilleur taux de compression si le contexte de compression est périodiquement ignoré

Créé le 8 juil. 2019  ·  3Commentaires  ·  Source: facebook/zstd

J'obtiens constamment un taux de compression légèrement meilleur si le contexte de compression n'est pas réutilisé.
Je crée un contexte de compression ZSTD, puis dans une boucle appelant ZSTD_compressCCtx, donnant à chaque fois 1 Mo de tampon avec des données. À la fin du processus, le contexte de compression est libéré.
Si je libère le contexte de compression et en crée un nouveau avant de procéder à la compression du tampon suivant de 1 Mo, la taille du fichier de sortie est systématiquement inférieure d'environ 1%.
Un autre fait intéressant est que le taux de compression est d'environ 1 à 1,5% meilleur si j'utilise des tampons d'entrée de 2 Mo avec des données, comparé à des tampons d'entrée de 1 Mo.
Dans mon cas d'utilisation, je ne suis pas limité par les ressources mémoire.
Des questions)

  • Est-il préférable de supprimer le contexte de compression entre la compression de gros morceaux de données?

    • Quelle est la taille optimale du tampon d'entrée recommandée (c'est-à-dire que la diminution de la taille du tampon dégradera le taux de compression, tandis que l'augmentation de la taille du tampon n'améliorera pas le taux de compression)?

    • Toute façon de dire à zstd "utilisez autant de mémoire que vous le souhaitez mais donnez-moi un meilleur taux de compression et / ou une meilleure vitesse"

    • Est-ce vraiment une compression en streaming avec contexte valable uniquement pour les cas d'utilisation limités en mémoire? Si j'ai beaucoup de mémoire, je ferais mieux de compresser indépendamment de grands tampons (> 1 Mo)?

question

Tous les 3 commentaires

Salut @scherepanov ,

ce résultat est surprenant.
En utilisant ZSTD_compressCCtx() , avec la même entrée et le même niveau de compression, peu importe (du point de vue du taux de compression) si le contexte est réutilisé ou non. Le seul impact de la réutilisation du contexte est de gagner du temps d'allocation et d'initialisation, c'est tout. Si cela a un impact sur le taux de compression, c'est étrange, et c'est probablement faux.

J'aimerais reproduire ce scénario si cela est possible. Quelle version utilisez-vous ?

Est-il préférable de supprimer le contexte de compression entre la compression de gros morceaux de données?

Vous ne devriez jamais avoir besoin de supprimer le contexte.
La seule «bonne» raison est de simplifier le code.
Mais du point de vue de la performance, cela ne devrait être que bénéfique, pas d'inconvénient.

Quelle est la taille optimale du tampon d'entrée recommandée

C'est très situationnel. Il n'y a pas de seuil «universel».
De manière générale, au-delà de la taille de la fenêtre 8x, l'augmentation de la taille des blocs est de moins en moins intéressante.
La taille de la fenêtre, cependant, est une valeur dynamique, en fonction du niveau de compression.
Il varie de 512 Ko (niveau 1) à 8 Mo (niveau 19).

Toute façon de dire à zstd "utilisez autant de mémoire que vous le souhaitez mais donnez-moi un meilleur taux de compression"

Le niveau 19 est censé être de ce genre

et / ou vitesse "

Le niveau 4 est généralement de ce type: il se compresse assez rapidement, mais utilise une quantité de mémoire démesurée. C'est le plus proche auquel je puisse penser.

Est-ce vraiment une compression en streaming avec contexte valable uniquement pour les cas d'utilisation limités en mémoire? Si j'ai beaucoup de mémoire, je ferais mieux de compresser indépendamment de grands tampons (> 1 Mo)?

La compression / décompression de morceaux indépendants en une seule passe ( ZSTD_compressCCtx() et ZSTD_decompressDCtx() ) est tout simplement plus simple et probablement aussi efficace que possible. Si vous pouvez le faire, c'est préférable. Le mode de streaming ajoute beaucoup de complexité en plus de cela. La complexité est principalement interne et cachée, mais l'idée principale est qu'elle ne peut pas être meilleure / plus rapide que la simple compression ou décompression en un seul passage.

Merci pour la réponse très clarifiante.
J'ai tracé un taux de compression différent pour un ordre différent de mes données. Oui, la réutilisation du contexte par rapport au rejet ne fait aucune différence, exactement comme vous l'avez dit. Désolé, je devrais être plus prudent et enquêter davantage avant de poser des questions.
Vos commentaires sont très clairs et très explicatifs. Je pense qu'il faut vraiment l'ajouter aux documents. Surtout en ce qui concerne la différence entre le streaming et le non-streaming - j'ai toujours pensé que le streaming est plus efficace, car vous pouvez mieux créer un dictionnaire (bien que vous ne sachiez pas comment modifier le dictionnaire lorsque les données changent dans un fichier). Il est très important de bien comprendre que le streaming est à peu près identique à la compression «basée sur des blocs». D'un autre côté, la diffusion en continu peut être plus efficace, car vous gérez automatiquement la taille des morceaux. J'utilise une taille de bloc de 1 Mo avec le niveau de compression par défaut 3, et je semble être insuffisant pour obtenir une meilleure compression. De ce point de vue, le streaming peut être plus efficace sur le taux de compression, car vous déterminerez la taille des morceaux de manière plus optimale. (Est-ce correct???)

le streaming est à peu près identique à la compression "basée sur des blocs"

Ce n'est pas exactement «pareil».

Si vous coupez les données d'entrée en morceaux et que vous les passez indépendamment à ZSTD_compressCCtx() , vous vous retrouvez avec plusieurs morceaux compressés indépendants. Chaque bloc compressé est une _frame_ indépendante. Ils peuvent être décompressés dans n'importe quel ordre, car chaque image est indépendante.

Si vous envoyez les mêmes données dans un seul flux, avec ZSTD_compressStream() , sans segmentation, vous vous retrouvez avec un _single frame_. En interne, le cadre est découpé en blocs, oui, mais cela n'a pas d'importance, car les blocs ne sont pas indépendants. Pour décoder n'importe quelle partie de l'image, il est nécessaire de tout décoder depuis le début.

En théorie, une seule image devrait mieux se compresser que plusieurs images indépendantes. En effet, couper les données en plusieurs segments indépendants leur fait perdre une opportunité de compression au début de chaque segment.
Cependant, les modes rapides ne sont que des compresseurs «probabilistes», qui font des paris hâtifs pour courir vite. Toutes les opportunités ne sont pas égales et parfois, la sélection d'une opportunité ne fait que masquer une meilleure opportunité ultérieure. C'est très spécifique aux données.
Par conséquent, dans de rares cas, il peut arriver que la découpe de données en blocs indépendants finisse par être compétitive avec un seul flux.
Mais je ne parierais pas là-dessus. Dans la plupart des cas, un seul flux devrait gagner, ne serait-ce que très peu.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

rgdoliveira picture rgdoliveira  ·  3Commentaires

robert3005 picture robert3005  ·  4Commentaires

sergeevabc picture sergeevabc  ·  3Commentaires

vade picture vade  ·  3Commentaires

ga92yup picture ga92yup  ·  3Commentaires