Определение лучшего алгоритма сжатия для использования для серии байтов - PullRequest
3 голосов
/ 03 марта 2009

Для моего личного проекта я пишу небольшой класс для сжатия и распаковки из довольно неясного формата. У меня есть полная спецификация, но проблема не в этом.

Во-первых, этот «формат» использует набор из 6 различных типов сжатия, а также несжатые блоки байтовых данных. Форматы: RLE, ответвление RLE, где число увеличивается на каждый байт (например, 3, 4, 5, ...), 16-битное RLE, LZ-Copy, обратное LZ-копирование и LZ-Copy Xor ' d с 255. Это не самая чистая из спецификаций, но я тоже ее не проектировал.

Моя подпрограмма сжатия должна принимать массив от 1 до 65535 байтов и (надеюсь) сжимать ее как можно больше. Моя предыдущая попытка просто вычислить, начиная с любого индекса в несжатом потоке, какой из методов сжатия, приведенных выше, обеспечит наилучшее сжатие, а затем сжимает сколько бы байтов этот метод ни сжал до массива сжатых байтов перед повторением из новый «несжатый» индекс, например:

{0,0,0,1,2,3,4}

Алгоритм сначала считал бы, что в начале было три нуля, а затем вывел бы для них кодировку RLE, которую использовала спецификация, а затем, начиная с четвертого элемента, прочитал бы, что увеличивающийся RLE будет покрывать '1,2 , 3,4 'достаточно хорошо и сожми это перед возвращением.

Обобщенная проблема заключается в том, что при попытке найти лучшую спецификацию для использования процедура очень медленна даже для небольших (20-30) байтовых массивов. Может ли кто-нибудь помочь с советами о том, как я могу смотреть на оптимизацию этого, или есть ли какая-либо дополнительная информация, которую я мог бы предоставить, чтобы помочь?

1 Ответ

0 голосов
/ 03 марта 2009

Похоже, что вы пытаетесь создать большое количество возможностей сжатия для каждого возможного сегмента (давайте назовем ваши сегменты переменной длины 1-64K блоков) файла. Поправьте меня, если я ошибаюсь, но вы разрабатываете лучшее сжатие для первого сегмента из следующих вариантов (метод 0 не сжат):

  • метод сжатия 0, длина 1 байт.
  • метод сжатия 1, длина 1 байт.
  • :::::
  • метод сжатия 6, длина 1 байт.
  • метод сжатия 0, длина 2 байта.
  • метод сжатия 1, длина 2 байта.
  • :::::
  • метод сжатия 6, длина 65534 байта.
  • метод сжатия 0, длина 65535 байт.
  • метод сжатия 1, длина 65535 байт.
  • метод сжатия 2, длина 65535 байт.
  • метод сжатия 3, длина 65535 байт.
  • метод сжатия 4, длина 65535 байт.
  • метод сжатия 5, длина 65535 байт.
  • метод сжатия 6, длина 65535 байт.

Это займет огромное количество времени (примерно 420 000 попыток сжатия на сегмент). Если это то, что вы делаете, вам лучше выбрать один размер сегмента (например, 64 КБ) и применить к нему каждый из семи методов сжатия, чтобы выбрать лучший. Затем для каждого сегмента выведите байт «method», а затем сжатые данные.

...