Table of Contents

Фундаментальная связь между сортировкой и компрессией

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

Алгоритмы сжатия без потерь, такие как кодирование Хаффмана, кодирование длины выполнения (RLE) и преобразование Барроуза-Уилера (BWT), полагаются на отсортированные или частично отсортированные данные для достижения высоких коэффициентов сжатия. Даже кодеки с потерями, такие как JPEG-2000, используют сортировку коэффициентов вейвлета для эффективного квантования. Понимая, как сортировка взаимодействует с сжатием, разработчики могут сделать осознанный выбор шагов предварительной обработки, выбора алгоритма и проектирования системы.

Как сортировка снижает энтропию

Энтропия, в теории информации, измеряет среднее количество информации, содержащейся в источнике. Высокая энтропия означает, что данные близки к случайному и трудно сжимаются. Сортировка уменьшает локальную энтропию путем кластеризации сходных значений вместе. Когда идентичные байты или токены появляются последовательно, простые схемы, такие как кодирование длины пробега, становятся чрезвычайно эффективными. Например, несортированная последовательность байтов может не иметь двух одинаковых значений рядом; после сортировки последовательность становится группами идентичных значений, резко снижая энтропию на байт. Это преобразование является основой компрессора (bzip2), который сначала применяет BWT — обратимое сортировочное преобразование — перед кодированием длины пробега и Хаффмана.

Сокращение энтропии не является глобальным; сортировка вводит другой тип структуры. Компрессор должен записывать первоначальный порядок (через обратное преобразование или перестановку), чтобы обеспечить реконструкцию без потерь. Но стоимость хранения этой перестановки обычно намного ниже, чем экономия от пониженной энтропии. Этот компромисс является центральным для многих современных компрессоров.

Сортировка как этап предварительной обработки

Многие системы сжатия применяют сортировку как стадию предварительной обработки. Барроуз-Уилер преобразует разделы входа в блоки, затем сортирует все циклические вращения каждого блока. Результатом является строка, которая сильно локализована — символы, которые часто встречаются во входе, становятся смежными. Этот выход после преобразования с шагом на фронт дает много нулевых байтов, которые затем сжимаются с RLE и Huffman. Аналогично, переднее преобразование дерева пакетов вейвлетов в величинах коэффициентов сжатия с потерями для приоритетизации больших коэффициентов для квантования.

Другим примером является использование сортировки в методах словаря Лемпеля-Зива. Словарь часто реализуется в виде хеш-таблицы или дерева. Если словарь сортируется (например, сортированный список фраз), бинарный поиск сокращает время поиска от O(n) до O(log n). Это ускорение становится критическим в высокопроизводительных трубопроводах сжатия, таких как те, которые используются в передаче данных в реальном времени.

Алгоритмы сортировки, используемые при сжатии

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

  • Quicksort широко используется для сортировки блоков в памяти из-за его среднего времени O(n log n) и низких накладных расходов. Многие реализации bzip2 используют сортировку для построения суффиксного массива BWT, хотя его худший вариант O(n2) может быть проблематичным для состязательных входов. Библиотеки часто возвращаются к куче или интрозорту.
  • Слияние является стабильным и предлагает гарантированное время O(n log n), что делает его хорошим для внешней сортировки, когда данные превышают ОЗУ.Некоторые инструменты сжатия, которые сортируют большие таблицы символов, используют вариант внешнего сливания.
  • Radix Sort является линейным по количеству бит на ключ, что делает его привлекательным для сортировки целых чисел (например, значений пикселей, подсчетов частоты). Он используется в некоторых компрессорах специального назначения для графики и научных данных, где ключи имеют фиксированную ширину. Его основным недостатком является потребление памяти для промежуточных ведер.
  • Интроспективный сорт (Introsort) начинается с быстрой сортировки, но переходит на кучу, когда глубина рекурсии превышает порог, сочетая скорость с безопасностью. Это тип по умолчанию в стандартной библиотеке C++ и появляется во многих трубопроводах сжатия, которые нуждаются в надежном наихудшем случае поведения.

Сортировка в технике сжатия без потерь

Алгоритмы сжатия без потерь используют избыточность, не уничтожая информацию.Сортировка естественным образом интегрируется в несколько из них, часто в качестве примитивной операции внутри кодера или в качестве предварительной трансформации.

Запуск-длинное кодирование (RLE) с сортированными данными

RLE заменяет последовательные идентичные символы счетом и символом. Его коэффициент сжатия полностью зависит от длины прогона. Сортировка ввода первой может преобразовывать случайную последовательность в длинные прогоны, резко повышая эффективность RLE. Например, черно-белые факсовые изображения (сжатие группы 4) используют двумерное кодирование длины прогона, которое извлекает выгоду из естественного упорядочения линий сканирования. В универсальных компрессорах сортировка часто сочетается с кодером перехода на фронт для получения длинных нулевых прогонов.

Huffman Coding и сортировка

Кодирование Хаффмана строит оптимальный префиксный код на основе частот символов. Сам алгоритм требует сортировки частот для эффективного построения двоичного дерева (обычно с использованием очереди приоритетов, которая является сортированной структурой). Кроме того, когда выход сортирующего преобразования подается в кодирование Хаффмана, результирующее распределение вероятности более искажено: высокочастотные символы (например, нули) встречаются с еще большей вероятностью, позволяя очень короткие кодовые слова. Это наблюдается в bzip2 и простых компрессорах Хаффмана, которые сначала применяют BWT плюс перемещение в фронт.

Алгоритмы Лемпеля-Зива и сортированные словари

Компрессоры на основе словарей, такие как LZ77, LZ78 и их производные (LZW, LZMA), поддерживают раздвижное окно или растущий словарь фраз. Сортированные структуры данных, такие как сбалансированные деревья или сортированные ключи хеш-таблицы, ускоряют поиск по самому длинному матчу. Например, zlib использует хеш-таблетку, цепь которой выигрывает от сортировки хеш-вкладышей. Более продвинутые компрессоры, такие как Zstandard (]github.com/facebook/zstd), используют чувствительный к шаблону подход, который использует сортированные последовательности во входе для улучшения поиска совпадений.

Burrows-Wheeler Transform (BWT) и сортировка

BWT, пожалуй, является наиболее прямой иллюстрацией роли сортировки в сжатии. Он строит матрицу всех циклических вращений блока и сортирует строки лексикографически. Последний столбец этой сортированной матрицы становится преобразованным выходом. Сортировка является вычислительным узким местом; качество сжатия полностью зависит от алгоритма сортировки, используемого для создания суффиксного массива. Современные реализации используют модифицированный сорт или линейно-временное суффиксное построение массива (]DOI-ссылка . После BWT данные очень поддаются кодированию длины прогона и энтропии. Обратный BWT также требует сортировки — он должен восстановить первоначальный порядок, реконструируя первый столбец из последнего столбца, используя тот факт, что первый столбец является сортированной версией последнего столбца. Таким образом, сжатие и декомпрессия зависят от эффективной сортировки.

Арифметическое кодирование и сортировка вероятностей

Арифметическое кодирование обеспечивает почти оптимальное сжатие для заданных вероятностей. Если вероятности символов изменяются в зависимости от контекста, контексты сортировки могут повысить точность оценки вероятности. Адаптивные арифметические кодеры часто поддерживают сортированный список пар контекст-символ, чтобы быстро найти соответствующее распределение вероятностей. Сортировка истории контекста также позволяет быстрее разделить интервал, поскольку диапазоны могут быть вычислены с использованием кумулятивных частот, хранящихся в двоичном индексированном дереве или сортированном массиве.

Роль сортировки в скорости декомпрессии

Декомпрессия должна быстро реконструировать исходные данные, часто с ограниченным объемом памяти. Сортировка ускоряет эту реконструкцию несколькими способами.

Быстрая декодировка с помощью сортированных структур данных

Многие сжатые форматы хранят метаданные (длины кода, смещения, подсчеты прогонов) в сортированном порядке. Например, таблицы кода Хаффмана сортируются по длине кода для ускорения поиска декодера. Когда длины кода монотонно не уменьшаются, декодер может использовать каноническое дерево Хаффмана, которое сводит поиск к простому побитовому обходу с использованием массива, индексируемого кумулятивным количеством. Сортировка символов по длине кодового слова делает это возможным. Аналогично, декомпрессоры LZ77 часто поддерживают сортированный кольцевой буфер, чтобы быстро найти смещение соответствия.

Обратная сортировка и реконструкция

Обратный BWT является примечательным примером: учитывая последний столбец L и индекс, указывающий на исходный первый символ, алгоритм строит первый столбец путем сортировки L. Этот шаг сортировки является наиболее трудоемкой частью декомпрессии BWT. Оптимизированные реализации используют индексированный связанный список или сорт подсчета (сорт ведра), потому что алфавит мал (обычно байты). Сорт подсчета работает во времени O (n + k), делая декомпрессию очень быстро. Без такого специализированного сортирования обратное преобразование было бы O (n log n), что неприемлемо для больших блоков.

Параллельные возможности

Сортировка, естественно, параллелизуема. Для сжатия многопоточные реализации могут сортировать блоки самостоятельно, затем сливать результаты (сортировать слияние). Для декомпрессии обратное преобразование каждого блока также можно сортировать независимо. Инструменты, такие как pbzip2 и pigz (параллельный gzip), используют это, расщепляя вход на куски, сжимая каждый со своей собственной стадией сортировки, а затем конкатенируя сжатые блоки. Это позволяет сортировать масштабирование с подсчетом ядра, делая сжатие и декомпрессию значительно быстрее на современном оборудовании. Например, pigz достигает почти линейного ускорения на многоядерных процессорах путем параллелизации трубопровода сжатия, включая этапы сортировки внутри каждого рабочего.

Сравнительный анализ алгоритмов сортировки для сжатия

Выбор правильного алгоритма сортировки может сделать разницу между быстрым компрессором производственного класса и медленным. Ниже мы сравниваем наиболее распространенные варианты.

Быстрый сорт против Мергесорта против Радикса Сорта

AlgorithmTime ComplexitySpace ComplexityBest Use Case
QuicksortO(n log n) average, O(n²) worstO(log n) in-placeIn‑memory block sorting (BWT)
MergesortO(n log n) guaranteedO(n) auxiliaryExternal sorting, stable requirements
Radix SortO(n * k) (k = bit width)O(n + 2^k)Fixed‑width integer keys (frequency, pixel values)

Для BWT сортировка быстрых сортировок распространена, но риск переполнения стека на патологических данных. Некоторые реализации (например, bzip2) переключаются на запасной вариант, если глубина рекурсии превышает предел. Mergesort предлагает предсказуемость за счет дополнительной памяти. Radix sort превосходит, когда ключевой диапазон мал (например, сортировка байтов, которые представляют собой 256 значений) - тогда сорт подсчета становится тривиальным и чрезвычайно быстрым.

Сортировка больших наборов данных: внешняя сортировка

При сжатии файлов, превышающих доступную оперативную память, весь набор данных не может быть отсортирован в памяти. Используются внешние алгоритмы сортировки (обычно вариант сортировки, который считывает и записывает временные файлы). Инструменты сжатия, такие как «bzip2» для больших файлов, разбивают вход в блоки (например, 900 КБ), сортируют каждый блок в памяти, а затем записывают сжатые блоки последовательно. Для еще больших наборов данных — таких как геномное сжатие или сжатие базы данных — необходимы более сложные внешние сортировки с использованием нескольких проходов. Современные компрессоры, такие как LZMA, могут обрабатывать произвольные входы с помощью раздвижного окна и не сортировать весь набор данных, а сортировать в конечном контексте. Компромисс между размером блока (который увеличивает стоимость сортировки) и коэффициентом сжатия является классическим инженерным решением.

Адаптивная сортировка и ее влияние на компрессию

Некоторые компрессоры адаптируют свою стратегию сортировки на основе характеристик данных. Например, компрессор может обнаружить, что вход уже почти отсортирован (например, текст после частичного BWT) и использовать сортировку ввода в качестве резервного, потому что сортировка ввода является O(n) на почти сортированных данных. Другие используют timsort, гибридный алгоритм стабильной сортировки, полученный из сортировки слияний и сортировки вставки, который используется в Python's list.sort() и в некоторых библиотеках сжатия для предварительной обработки. Timsort использует естественные забеги в данных, уменьшая количество сравнений. Это может быть полезно при сжатии данных, которые уже имеют некоторый порядок, например, отсортированные таблицы баз данных или дополнительные резервные копии.

Практические применения и оптимизации

Синергия между сортировкой и сжатием проявляется во многих реальных системах.

Сортировка в сжатии базы данных

Базы данных, ориентированные на колонку (например, Apache Parquet, ORC), хранят каждую колонку отдельно и часто сортируют строки для улучшения сжатия. Сортировка по колонке (или набору столбцов) значительно улучшает кодирование длины строки: если колонка сортируется, все идентичные значения становятся смежными, что приводит к длинным прогонам, которые сжимаются до нескольких байтов. Современные системы баз данных также используют сжатие словарей на отсортированных словарях, которые являются просто отсортированными списками различных значений. Сортировка словаря не только ускоряет поиск по двоичному поиску, но и повышает эффективность самого словаря, группируя похожие ключи. Например, Apache Parquet позволяет пользователям определять порядок сортировки на группу столбцов, что приводит к значительной экономии хранения.

Фото и видео сжатие

При сжатии с потерями вейвлет-преобразует (например, JPEG-2000, Dirac) разложить изображение на поддиапазоны коэффициентов. Эти коэффициенты затем квантоваются и кодируются. Сортировка коэффициентов по величине перед кодированием (этап, называемый «размножением значимости») позволяет кодировщику сначала отправить самые большие коэффициенты, достигая прогрессивного битового потока. Встроенный алгоритм вейвлета с нулевым деревом (EZW) и разделение на множество в иерархических деревьях (SPIHT) полагаются на сортировку величин коэффициента. Аналогично, в сжатии видео векторы движения и коэффициенты DCT могут быть отсортированы для улучшения контекстного арифметического кодирования (как в H.264 / AVC CABAC).

Сжатие текста

Текстовые компрессоры, такие как PPM (предсказание путем частичного сопоставления), часто сортируют контексты, в которых появляется символ. Дерево суффикса или массив суффикса, используемые во многих схемах сжатия текста (например, для корреляций на большие расстояния), требуют сортировки всех суффиксов ввода. Это в принципе идентично BWT. Компрессоры, такие как «szip» для научных данных, используют сортированные истории символов для построения моделей Маркова высокого порядка. Сортировка списков контекста обычно выполняется с сортировкой по радику на уровнях символов, используя алфавит фиксированной ширины ASCII / байт.

Сеть Data Spression

Сетевые протоколы часто сжимают заголовки или полезные нагрузки. Например, сжатие заголовков IP (RFC 2507) использует сортировку полей заголовков для идентификации дельт. Некоторые прозрачные прокси сжатия сортируют пакетные полезные нагрузки в буфере перед применением zip-подобного сжатия. В то время как накладные расходы на сортировку небольшого буфера низки, коэффициент усиления в сжатии может быть значительным, потому что сортированные полезные нагрузки имеют длинные пробеги идентичных байтов. Этот метод используется в некоторых беспроводных протоколах сети датчиков, где энергоэффективность имеет первостепенное значение.

Заключение

Сортировка алгоритмов гораздо больше, чем академические упражнения; они являются практическими двигателями, которые ускоряют как сжатие данных, так и декомпрессию. Путем снижения энтропии, позволяя сложные преобразования, такие как BWT, и ускоряя поиск в словаре, сортировка обеспечивает структуру, которую алгоритмы сжатия должны достичь высоких соотношений. Кроме того, те же сортированные структуры, которые помогают сжатию, также упрощают и ускоряют декомпрессию, особенно при использовании линейно-временных сортировок для небольших алфавитов.

При проектировании конвейера сжатия инженеры должны тщательно рассмотреть выбор алгоритма сортировки — баланс скорости, памяти и поведения в худшем случае. Независимо от того, использует ли он сортировку для преобразования блоков, сортировку радикса для операций на байтовом уровне или внешний сорт для наборов данных в масштабе терабайтов, правильный алгоритм сортировки может сделать систему быстрой и эффективной. По мере того, как объемы данных продолжают расти, а сжатие перемещается в более специализированные области (научные вычисления, геномика, видео в реальном времени), брак сортировки и сжатия будет только более критичным.

Для дальнейшего чтения см. статью Burrows-Wheeler Transform в Википедии, Zstandard compression library и исследовательский документ по быстрой сортировке для сжатия данных (IEEE, 2015).