Прямой ответ
Алгоритм сжатия выбирается по соотношению коэффициента сжатия и скорости, поскольку оба параметра связаны обратной зависимостью: большее сжатие требует больше вычислений.
| Алгоритм | Относительная скорость | Относительный коэффициент |
|---|---|---|
| lz4 | Высокая | Низкий |
| zstd (низкие уровни) | Высокая | Средний |
| zstd (высокие уровни) | Низкая | Высокий |
| gzip | Средняя | Средний |
| brotli | Низкая | Высокий |
# Сравнение на собственном файле
gzip -9 -c data.json > data.json.gz
zstd -19 -c data.json > data.json.zst
lz4 -9 -c data.json > data.json.lz4
ls -l data.json data.json.gz data.json.zst data.json.lz4
Коэффициент сжатия определяется как отношение исходного размера к сжатому; о методике измерения — в статье про оценку коэффициента сжатия.
Выбор зависит от того, что ограничивает: объём хранения либо время обработки. При передаче данных по сети сжатие сокращает объём передачи, но добавляет время на сжатие и распаковку; о соотношении — в статье про сжатие и скорость доступа.
Сжатие без потерь, словари и пригодность данных
Все перечисленные алгоритмы выполняют сжатие без потерь: исходные данные восстанавливаются побайтово. Различия касаются эффективности и скорости.
Пригодность данных. Коэффициент сжатия зависит от избыточности данных. Текстовые данные с повторяющимися шаблонами сжимаются в несколько раз, случайные либо уже сжатые данные почти не сжимаются.
Словари. Алгоритмы с поддержкой словарей используют заранее обученный набор шаблонов, поэтому сжимают малые порции данных эффективнее. Словарь обучается на выборке данных того же вида.
Уровень сжатия. Один алгоритм с разными уровнями даёт разное соотношение коэффициента и скорости; о настройке уровней — в статье про zstd.
Практическое следствие: коэффициент сжатия, измеренный на чужих данных, не переносится на собственные, поскольку избыточность различается.
Три признака непригодности данных для сжатия.
Данные уже сжаты. Изображения, видео и архивы содержат мало избыточности, поэтому повторное сжатие почти не уменьшает объём, но расходует время.
Данные зашифрованы. Шифрование устраняет избыточность, поэтому сжатие после шифрования неэффективно. Порядок операций: сжатие, затем шифрование.
Порции слишком малы. Заголовок алгоритма занимает фиксированный объём, поэтому на малых порциях сжатие может увеличить размер.
Отдельный аспект — стоимость распаковки. Распаковка обычно быстрее сжатия, поэтому асимметрия учитывается при выборе: данные, которые читаются часто, сжимаются алгоритмом с быстрой распаковкой.
Практика: выбор и проверка алгоритма сжатия
1. Определите ограничение. Объём хранения либо время обработки определяет приоритет коэффициента либо скорости.
2. Измерьте на собственных данных. Коэффициент сжатия зависит от избыточности, поэтому тест на чужих данных не переносится.
3. Проверьте несколько уровней. Один алгоритм с разными уровнями даёт разное соотношение, поэтому измеряется несколько вариантов.
4. Учтите стоимость распаковки. Данные, которые читаются часто, требуют быстрой распаковки.
5. Не сжимайте уже сжатые данные. Повторное сжатие расходует время без уменьшения объёма.
6. Соблюдайте порядок сжатия и шифрования. Сжатие выполняется до шифрования, поскольку шифрование устраняет избыточность.
7. Проверьте поведение на малых порциях. Заголовок алгоритма занимает фиксированный объём, поэтому на малых данных сжатие может увеличить размер.
Рекомендации:
- Различайте сжатие и архивацию. Сжатие уменьшает объём, архивация объединяет несколько объектов в один; о хранении — в статье про архивацию данных.
- Учитывайте потребление памяти. Алгоритмы с высоким коэффициентом требуют больше памяти на сжатие и распаковку.
- Проверяйте совместимость формата. Формат сжатия должен поддерживаться всеми потребителями данных.
- Фиксируйте уровень сжатия в конфигурации. Изменение уровня влияет на время обработки и объём, поэтому значение фиксируется явно.
- Пересматривайте выбор при изменении данных. Изменение состава данных изменяет избыточность, поэтому коэффициент сжатия меняется.
Практический сценарий: сжатие увеличило время загрузки без выигрыша в объёме
Контекст: сжатие включено для ускорения передачи данных, но время загрузки выросло, а объём почти не изменился.
- Диагностика. Данные представляли собой уже сжатые изображения, передаваемые в теле ответа. Сжатие выполнялось на каждом запросе, коэффициент составил единицу с небольшим, поэтому объём передачи не сократился.
- Причина. Сжатие применено к данным без избыточности. Время на сжатие добавилось к каждому запросу, а выигрыш в объёме передачи отсутствовал, поэтому общее время выросло.
- Действия. (а) Измерили коэффициент сжатия на фактических данных и убедились, что он близок к единице; (б) отключили сжатие для типов содержимого, которые уже сжаты; (в) оставили сжатие для текстовых ответов, где коэффициент составил несколько единиц; (г) добавили проверку типа содержимого перед применением сжатия; (д) зафиксировали в конфигурации перечень типов, к которым сжатие применяется.
- Результат. Время обработки текстовых ответов сократилось за счёт меньшего объёма передачи, а сжатие изображений не выполняется.
Вывод: сжатие данных без избыточности расходует время без уменьшения объёма. Проверка коэффициента на фактических данных определяет, к каким типам содержимого сжатие применять.
FAQ
Какой алгоритм даёт наибольшее сжатие? Коэффициент зависит от данных, поэтому сравниваются алгоритмы на собственном наборе. Алгоритмы с высоким коэффициентом требуют больше времени и памяти.
Можно ли сжать уже сжатые данные? Технически да, но коэффициент близок к единице, поскольку избыточность уже устранена. Повторное сжатие расходует время без выигрыша.
В каком порядке выполнять сжатие и шифрование? Сначала сжатие, затем шифрование. Шифрование устраняет избыточность, поэтому сжатие после шифрования неэффективно.
Почему сжатие малых порций неэффективно? Заголовок алгоритма занимает фиксированный объём, поэтому на малых данных он составляет заметную долю результата.
Источники: Zstandard, gzip, LZ4 — ссылки в шапке.