Стратегии Java Deflater - DEFAULT_STRATEGY, FILTERED и HUFFMAN_ONLY - PullRequest
5 голосов
/ 27 марта 2010

Я пытаюсь найти баланс между производительностью и степенью сжатия при распаковке ответа Java-приложения.

Глядя на класс Deflater, я могу установить уровень и стратегию. Уровни говорят сами за себя - от BEST_SPEED до BEST_COMPRESSION.

Я не уверен насчет стратегий - DEFAULT_STRATEGY, FILTERED и HUFFMAN_ONLY

Я могу иметь некоторый смысл от Javadoc, но мне было интересно, использовал ли кто-то определенную стратегию в своих приложениях, и видели ли вы какие-либо различия с точки зрения производительности / степени сжатия.

1 Ответ

14 голосов
/ 27 марта 2010

Опции стратегии, упомянутые в Java Deflater, возникли в реализации ZLIB в zlib (C) и ( RFC 1950 ) и DEFLATE ( 1951 ), я полагаю. Они присутствуют практически во всех библиотеках сжатия, которые реализуют DEFLATE.

Чтобы понять, что они означают, вам нужно немного узнать о DEFLATE . Алгоритм сжатия сочетает в себе LZ77 и кодирование Хаффмана. Основы:

  • Сжатие LZ77 работает путем поиска последовательностей данных, которые повторяются. Реализации, как правило, используют «скользящее окно» от 1 до 32 тыс., Чтобы отслеживать данные, которые были до этого. Для любых повторов в исходных данных вместо вставки повторяющихся данных в вывод, сжатие LZ77 вставляет «обратную ссылку». Представьте себе обратную ссылку, говорящую «здесь, вставьте те же данные, которые вы видели 8293 байта назад, для 17 байтов». Бэк-реф кодируется в виде этой пары чисел: длина - в данном случае 17 - и расстояние (или смещение) - в данном случае 8293.

  • Кодирование Хаффмана заменяет коды на фактические данные. Когда данные указывают на X, код Хаффмана говорит на Y. Это, очевидно, помогает сжатию, только если замена короче, чем оригинал. (контрпример в фильме Джима Керри Да, мужик , когда Норм использует «Car» в качестве короткого имени для Карла. Карл указывает, что Карл уже довольно короткий.) Алгоритм кодирования Хаффмана делает частоту анализ и использует самые короткие замены для последовательностей данных, которые встречаются чаще всего.


Deflate объединяет их, так что можно использовать коды Хаффмана в ссылках на LZ77. Варианты стратегии на различных компрессорах DEFLATE / ZLIB просто говорят библиотеке, сколько весить Хаффмана против LZ77.

  • FILTERED обычно означает, что спички LZ77 останавливаются на длине 5. Поэтому, когда в документации написано

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

    (из справочной страницы zlib )
    ... мое прочтение кода говорит о том, что оно выполняет сопоставление LZ77, но только до последовательностей в 5 или менее байтов. Это то, что документ подразумевает под «маленькими значениями», я думаю. Но число 5 не упоминается в документе, поэтому нет гарантии, что число не будет изменено с rev на rev или с одной реализации ZLIB / DEFLATE на другую (например, версию C и версию Java).

  • HUFFMAN_ONLY говорит, что только коды замещения основаны на частотном анализе. HUFFMAN_ONLY очень, очень быстро, но не очень эффективно для сжатия большинства данных. Если у вас не очень маленький диапазон значений байтов (например, если байты в вашем фактическом потоке данных принимают одно из 20 возможных значений из 255), или если у вас экстремальные требования к скорости сжатия за счет размера, HUFFMAN_ONLY будет не быть тем, что вы хотите.

  • DEFAULT объединяет оба способа так, как авторы ожидали, что это будет наиболее эффективно для большинства приложений.


Насколько я знаю, в DEFLATE нет способа сделать только LZ77. Стратегии LZ77_ONLY нет. Но, конечно, вы можете построить или приобрести свой собственный кодировщик LZ77, и это будет «только LZ77».


Имейте в виду, что стратегия никогда не влияет на правильность сжатия; это влияет только на его работу и производительность, как по скорости, так и по размеру.


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


Суть в том, что для случая 80% вам не нужно настраивать стратегию. Возможно, вам будет интересно поиграться с оконными битами, просто чтобы посмотреть, что происходит. Но делайте это только тогда, когда вы сделали все остальное, что вам нужно сделать в вашем приложении.


справка:
Как работает DEFLATE, Antaeus Feldspar

...