Стоит ли пытаться уменьшить размер JSON?
Я отправляю относительно много данных из мобильного приложения (до 1000 объектов JSON), которые я обычно кодировал бы следующим образом:
[{
id: 12,
score: 34,
interval: 5678,
sub: 9012
}, {
id: ...
}, ...]
Я мог бы сделать полезную нагрузку меньше, отправив массив массивов:
[[12, 34, 5678, 9012], [...], ...]
чтобы сохранить некоторое пространство в именах свойств и воссоздать объекты на сервере (поскольку схема исправлена или, по крайней мере, это контракт между сервером и клиентом).
Полезная нагрузка затем отправляется в запрос POST
, скорее всего, через соединение 3G (или может быть Wi-Fi).
Похоже, что я сохраняю некоторую пропускную способность с помощью вложенных массивов, но я не уверен, что это заметно при применении gzip, и я не уверен, как точно и объективно измерить разницу.
С другой стороны, вложенные массивы не кажутся хорошей идеей: они менее читаемы и, следовательно, сложнее обнаружить ошибки при отладке. Кроме того, поскольку мы очищаем читаемость в унитазе, мы можем просто сгладить массив, поскольку каждый дочерний массив имеет фиксированное количество элементов, сервер может просто нарезать его и снова восстановить объекты.
Любые дополнительные материалы для чтения по этой теме очень ценятся.
Ответы
Ответ 1
JSONH, aka hpack, https://github.com/WebReflection/JSONH делает что-то очень похожее на ваш пример:
[{
id: 12,
score: 34,
interval: 5678,
sub: 9012
}, {
id: 98,
score: 76,
interval: 5432,
sub: 1098
}, ...]
Повернулся бы:
[["id","score","interval","sub"],12,34,5678,9012,98,76,5432,1098,...]
Ответ 2
JSON предназначен для удобочитаемости. У вас может быть промежуточный формат, если вы обеспокоены пространством. Создайте функцию serialize/deserialize, которая берет JSON файл и создает сжатый двоичный файл, сохраняя ваши данные как можно компактнее, а затем читайте этот формат на другом конце строки.
Смотрите: http://en.wikipedia.org/wiki/Json
Первое предложение: "JSON... - это легкий текстовый открытый стандарт, предназначенный для обмена информацией, доступный для человека".
По сути, я хочу сказать, что люди всегда будут видеть JSON, и машины будут в первую очередь видеть двоичный файл. Вы получаете лучшее из обоих миров: читаемость и небольшая передача данных (за счет небольшого количества вычислений).
Ответ 3
Gzip заменит повторяющиеся части вашего сообщения небольшими обратными ссылками на их первое появление. Алгоритм довольно "тупой", но для такого рода повторяющихся данных это замечательно. Я думаю, вы не увидите заметного уменьшения размера проводов, потому что ваша "структура" объекта отправляется только один раз.
Вы можете грубо проверить это, запустив два образца JSON. Или путем захвата HTTP-запроса с использованием Fiddler. Он может отображать сжатые и несжатые размеры.
Ответ 4
Поскольку вы используете это на мобильном устройстве (вы упоминаете 3G), вы можете действительно заботиться о размере, а не о читаемости. Более того, вы часто ожидаете, что прочитаете то, что передается по проводу?
Это предложение для альтернативной формы.
ProtoBuf - один из вариантов. Google использует его внутри, и есть компилятор ProtoBuf, который может читать .proto
файлы (содержащие описание сообщения) и генерировать сериализаторы/десериализаторы Java/С++/Python, которые используют двоичную форму для передача по проводам. Вы просто используете сгенерированные классы на обоих концах и забываете о том, как выглядит объект при передаче по проводу. Существует также порт Obj-C, поддерживаемый внешне.
Вот сравнение ProtoBuf против XML на веб-сайте ProtoBuf (я знаю, что XML еще не используется).
Наконец, вот учебник Python.
Ответ 5
Хотя старый вопрос, я хотел бы добавить несколько слов.
По моему опыту, большие различия в размере json raw, очень мало после сжатия. Я предпочитаю держать его в человеческом понимании.
В реальных номерах: json файл 1,29 МБ и оптимизированная версия 145 КБ при сжатии, где 32 КБ и 9 КБ.
За исключением экстремальных условий, я думаю, что такие разногласия - это небрежности, а стоимость в читаемости огромна.
А:
{
"Code": "FCEB97B6",
"Date": "\/Date(1437706800000)\/",
"TotalQuantity": 1,
"Items": [
{
"CapsulesQuantity": 0,
"Quantity": 1,
"CurrentItem": {
"ItemId": "SHIELD_AXA",
"Order": 30,
"GroupId": "G_MODS",
"TypeId": "T_SHIELDS",
"Level": 0,
"Rarity": "R4",
"UniqueId": null,
"Name": "AXA Shield"
}
}
],
"FormattedDate": "2015-Jul.-24"
}
В:
{
"fDate": "2016-Mar.-01",
"totCaps": 9,
"totIts": 14,
"rDays": 1,
"avg": "1,56",
"cells": {
"00": {
"30": 1
},
"03": {
"30": 1
},
"08": {
"25": 1
},
"09": {
"26": 3
},
"12": {
"39": 1
},
"14": {
"33": 1
},
"17": {
"40": 3
},
"19": {
"41": 2
},
"20": {
"41": 1
}
}
}
Это фрагменты двух файлов.