Алгоритм сжатия для JSON-кодированных пакетов?
Каким будет лучший алгоритм сжатия для сжатия пакетов перед отправкой их по проводу? Пакеты кодируются с использованием JSON. Будет ли LZW быть хорошим для этого или есть что-то лучше?
Ответы
Ответ 1
Я думаю, что два вопроса повлияют на ваш ответ:
1) Насколько хорошо вы можете предсказать состав данных, не зная, что произойдет при каком-либо конкретном запуске программы? Например, если ваши пакеты выглядят так:
{
"vector": {
"latitude": 16,
"longitude": 18,
"altitude": 20
},
"vector": {
"latitude": -8,
"longitude": 13,
"altitude": -5
},
[... et cetera ...]
}
- тогда вы, вероятно, получите лучшее сжатие, создав жестко закодированный словарь текстовых строк, которые будут отображаться в ваших данных, и замените каждое вхождение одной из текстовых строк на соответствующий индекс словаря. (На самом деле, если ваши данные были этим регулярными, вы, вероятно, захотите отправить только значения по проводу и просто написать функцию в клиенте для создания объекта JSON из значений, если необходим объект JSON.)
Если вы не можете предсказать , какие заголовки будут использоваться, вам может потребоваться использовать LZW или LZ77 или другой метод, который просматривает уже прошедшие данные, чтобы найти данные, которые он может выразить в особенно компактной форме. Однако...
2) Нужно ли упаковывать пакеты отдельно друг от друга? Если это так, то LZW определенно не метод, который вы хотите; он не успеет построить свой словарь до размера, который даст существенные результаты сжатия к концу одного пакета. Единственный шанс получить действительно существенное сжатие в этом сценарии, IMHO, - это использовать закодированный словарь.
(Добавление ко всему вышесказанному: как указывает Майкл Коне, отправка JSON означает, что вы, вероятно, отправляете весь текст, а это означает, что вы недостаточно используете пропускную способность, которая имеет возможность отправлять гораздо более широкий диапазон символов, чем вы Однако проблема о том, как упаковывать символы, попадающие в диапазон 0-127, в контейнеры, которые содержат значения 0-255, довольно проста, и я думаю, что это может быть оставлено как "упражнение для читателя", как говорится.)
Ответ 2
Есть еще два алгоритма сжатия JSON: CJson и HPack
HPack выполняет очень хорошую работу, сравнимую с сжатием gzip.
Ответ 3
Ummm... Исправьте меня, если я ошибаюсь, но если вы выполняете сжатие по кабелю, то вы управляете обоими концами соединения, правильно? В этом случае, если JSON слишком толст, протокол, почему бы вам просто не выбрать другой проводной протокол, который не является таким же жирным? Я имею в виду, я понимаю привлекательность использования стандарта, такого как JSON, но если вас беспокоит пропускная способность, то вам, вероятно, следует выбрать проводной протокол, который не является всем текстом.
Ответ 4
Пусть веб-сервер сжимается и браузер распаковывается изначально; gzip или deflate.
Ответ 5
Ниже приведен короткий тест на сжимаемость данных JSON
оригинал: crime-data_geojson.json 72844By
(Вы можете получить файл здесь: https://github.com/lsauer/Data-Hub. Файл был выбран случайным образом, но не может быть репрезентативным для средних данных JSON)
кроме zip все параметры архиватора были установлены на ultra
* cm/ nanozip:
> 4076/72844
[1] 0.05595519
* gzip:
> 6611/72844
[1] 0.09075559
* LZMA / 7zip
> 5864/72844
[1] 0.0805008
* Huffman / zip:
> 7382/72844
[1] 0.1013398
* ?/Arc:
> 4739/72844
[1] 0.06505683
Это означает, что сжатие очень высокое и выгодное. Данные JSON обычно имеют высокую энтропию. Согласно wikipedia
Скорость энтропии английского текста составляет от 1,0 до 1,5 бит на буквы, [1] или от 0,6 до 1,3 бит на букву, согласно оценки Шеннона на основе человеческих экспериментов
Энтропия данных JSON часто намного выше. (В эксперименте с 10 произвольными JSON файлами примерно равного размера i, вычисленными 2.36)
Ответ 6
Gzip (алгоритм спускания) довольно хорош при сжатии, хотя, как и все хорошие алгоритмы сжатия, использует множество процессоров (в 3-5 раз больше, чем накладные расходы на чтение/запись json при тестировании).