Zstd: Лучшая степень сжатия, если контекст сжатия периодически отбрасывается

Созданный на 8 июл. 2019  ·  3Комментарии  ·  Источник: facebook/zstd

Я постоянно получаю немного лучшую степень сжатия, если контекст сжатия не используется повторно.
Я создаю контекст сжатия ZSTD, затем в цикле вызываю ZSTD_compressCCtx, каждый раз предоставляя буфер размером 1 МБ с данными. В конце процесса контекст сжатия освобождается.
Если я освобождаю контекст сжатия и создаю новый, прежде чем приступить к сжатию следующего буфера размером 1 МБ, размер выходного файла будет постоянно примерно на 1% меньше.
Еще один интересный факт заключается в том, что степень сжатия примерно на 1–1,5% лучше, если я использую входные буферы объемом 2 МБ с данными, по сравнению с буферами ввода 1 МБ.
В моем случае я не ограничен ресурсами памяти.
Вопросов)

  • Лучше ли отказаться от контекста сжатия между сжатием больших блоков данных?

    • Какой рекомендуемый оптимальный размер входного буфера (т.е. уменьшение размера буфера ухудшит степень сжатия, а увеличение размера буфера не улучшит степень сжатия)?

    • Любой способ сказать zstd «используйте столько памяти, сколько хотите, но дайте мне лучшую степень сжатия и / или скорость»

    • Действительно ли потоковое сжатие с контекстом подходит только для случаев использования с ограничением памяти? Если у меня много памяти, мне лучше самостоятельно сжимать большие (> 1 МБ) буферы?

question

Все 3 Комментарий

Привет @scherepanov!

этот результат удивителен.
При использовании ZSTD_compressCCtx() с тем же вводом и одинаковым уровнем сжатия не должно иметь значения (с точки зрения степени сжатия), используется ли контекст повторно или нет. Единственное влияние повторного использования контекста - это экономия времени на выделение и инициализацию, вот и все. Если это влияет на степень сжатия, это странно и, вероятно, неправильно.

Я хотел бы воспроизвести этот сценарий, если это возможно. Какую версию вы используете?

Лучше ли отказаться от контекста сжатия между сжатием больших блоков данных?

Вы никогда не должны отказываться от контекста.
Единственная «веская» причина - упростить код.
Но с точки зрения производительности это должно быть только на пользу, а не на минусах.

Какой рекомендуемый оптимальный размер входного буфера

Это в высшей степени ситуативно. Нет «универсального» порога.
Вообще говоря, если размер окна превышает 8x, увеличение размера блока становится все менее и менее ценным.
Однако размер окна - это динамическое значение, зависящее от уровня сжатия.
Он варьируется от 512 КБ (уровень 1) до 8 МБ (уровень 19).

Любой способ сказать zstd «используйте столько памяти, сколько хотите, но дайте мне лучшую степень сжатия»

19 уровень должен быть таким

и / или скорость "

Уровень 4 обычно такой: он сжимается довольно быстро, но использует слишком большой объем памяти. Это самое близкое, что я могу придумать.

Действительно ли потоковое сжатие с контекстом подходит только для случаев использования с ограничением памяти? Если у меня много памяти, мне лучше самостоятельно сжимать большие (> 1 МБ) буферы?

Сжатие / распаковка независимых фрагментов за один проход ( ZSTD_compressCCtx() и ZSTD_decompressDCtx() ) просто проще и, вероятно, настолько эффективно, насколько это возможно. Если вы можете это сделать, это предпочтительнее. Потоковый режим добавляет к этому много сложностей. Сложность в основном внутренняя и скрытая, но основная идея заключается в том, что она не может быть лучше / быстрее, чем простое однопроходное сжатие или распаковка.

Спасибо за очень подробный ответ.
Я проследил разную степень сжатия для разного порядка моих данных. Да, повторное использование контекста и отбрасывание не имеет значения, в точности как вы сказали. Извините, мне следует быть более осторожным и исследовать больше, прежде чем задавать вопросы.
Ваши комментарии очень четкие и очень объясняющие. Я думаю, это действительно нужно добавить в документы. В частности, о разнице между потоковой передачей и без потоковой передачи - мне всегда казалось, что потоковая передача более эффективна, поскольку вы можете лучше создавать словарь (хотя неясно, как вы изменяете словарь при изменении данных в файле). Очень важно четкое понимание того, что потоковая передача во многом похожа на "блочное" сжатие. С другой стороны, потоковая передача может быть более эффективной, поскольку вы автоматически обрабатываете размер блока. Я использую размер блока размером 1 МБ с уровнем сжатия 3 по умолчанию, и, похоже, этого недостаточно для улучшения сжатия. С этой точки зрения потоковая передача может быть более эффективной с точки зрения степени сжатия, поскольку вы определите размер блока более оптимальным образом. (Это правильно???)

потоковая передача почти такая же, как "блочное" сжатие

Это не совсем то же самое.

Если вы разрежете входные данные на фрагменты и передадите их независимо ZSTD_compressCCtx() , вы получите несколько независимых сжатых фрагментов. Каждый сжатый фрагмент представляет собой независимый _frame_. Их можно распаковать в любом порядке, потому что каждый кадр независим.

Если вы отправляете одни и те же данные в один поток с ZSTD_compressStream() без разбиения на части, вы получите _single frame_. Внутри кадр разбит на блоки, да, но это не имеет значения, потому что блоки не являются независимыми. Чтобы декодировать любую часть кадра, необходимо декодировать все сначала.

Теоретически один кадр должен сжиматься лучше, чем несколько независимых кадров. Это связано с тем, что разделение данных на несколько независимых фрагментов приводит к потере некоторой возможности сжатия в начале каждого фрагмента.
Однако быстрые режимы - это просто «вероятностные» компрессоры, которые делают поспешные ставки, чтобы работать быстро. Не все возможности равны, и иногда выбор одной возможности просто маскирует более позднюю лучшую возможность. Это очень специфично для данных.
Следовательно, в некоторых редких случаях может случиться так, что разделение данных на независимые фрагменты окажется конкурентоспособным с одним потоком.
Но я бы не стал на это ставить. В большинстве случаев одиночный поток должен выиграть, хотя бы совсем немного.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

escalade picture escalade  ·  3Комментарии

rgdoliveira picture rgdoliveira  ·  3Комментарии

robert3005 picture robert3005  ·  4Комментарии

animalize picture animalize  ·  3Комментарии

TheSil picture TheSil  ·  3Комментарии