2011-02-03 6 views
11

Существуют ли какие-либо компактные двоичные представления JSON? Я знаю, что есть BSON, но даже на этой веб-странице говорится, что «во многих случаях не намного эффективнее JSON. В некоторых случаях BSON использует еще больше места, чем JSON».компактное двоичное представление json

Я ищу формат, который настолько компактен, насколько это возможно, желательно какой-то открытый стандарт?

+0

Почему вы не можете использовать сжатие на сервере? – Andrey

+1

Спецификации BSON далеко не оптимальны как по размеру, так и по эффективности. Возможно, вам стоит рассмотреть возможность хранения сжатого JSON (с дефлятом или что-то еще). – arthurprs

+0

@ Андрей может быть возможным решением, но я хочу посмотреть, есть ли способ уменьшить количество данных, которые мы кормим, в базовый поток (который уже имеет возможность делать сжатие «на лету»). в теории, это должно быть проще сжать его на уровне кодирования объекта, так как у нас есть контекст о тегах и т. д. –

ответ

7

Да: Smile формат данных. Это относительно новый формат передачи данных, имеет публичную реализацию Java, версию C в работах в github (libsmile). Он имеет преимущество быть более компактным, чем JSON (надежно), но на 100% совместимой логической модели данных, поэтому легко и легко конвертировать туда и обратно с текстовым JSON.

Для исполнения вы можете увидеть jvm-serializers эталон, где улыбка хорошо конкурирует с другими бинарными форматами (бережливость, avro, protobuf); это не самый компактный (поскольку он сохраняет имена полей), но гораздо лучше работает с потоками данных, где имена повторяются.

Он используется некоторыми проектами (например, Elastic Search, Protostuff-rpc поддерживает его), хотя и не так широко, как сказать Thrift.

EDIT (декабрь 2011) - теперь есть также привязки libsmile для PHP, Ruby и Python, поэтому поддержка языка улучшается. Кроме того, существуют измерения размера данных; и хотя для альтернативных данных с одной записью (Avro, protobuf) более компактны, для потоков данных Smile часто более компактен из-за ключа и параметра ссылки на значение String.

+0

Улыбка: странные спецификации, несмотря на цели проекта. – arthurprs

+0

Ухаживать за разработкой? Конструктивная критика приветствуется :) – StaxMan

+0

Спасибо! это именно то, что я искал –

0

Попробуйте использовать js-inflate, чтобы создавать и снимать капли.

https://github.com/augustl/js-inflate

Это идеальный вариант, и я использую много.

3

gzipping Данные JSON обеспечат вам хорошие коэффициенты сжатия с минимальными усилиями из-за его универсальной поддержки. Кроме того, если вы находитесь в среде браузера, вы можете заплатить большую байтовую стоимость в зависимости от зависимости от новой библиотеки, чем при реальной экономии полезной нагрузки.

Если ваши данные имеют дополнительные ограничения (например, множество избыточных значений полей), вы можете оптимизировать работу, рассматривая другой протокол сериализации, а не придерживаться JSON. Пример: сериализация на основе столбцов, такая как Avro's upcoming columnar store, может дать вам лучшие коэффициенты (для хранения на диске). Если ваша полезная нагрузка содержит множество постоянных значений (например, столбцы, представляющие перечисления), может оказаться полезным подход сжатия словаря.

11

Вы можете взглянуть на Universal Binary JSON specification. Он не будет столь же компактным, как Smile, потому что он не ссылается на имена, но на 100% совместим с JSON (где BSON и BJSON определяют структуры данных, которых нет в JSON, поэтому нет стандартного преобразования в/из).

Это также (преднамеренно) преступно просто читать и писать со стандартным форматом:

[type, 1-byte char]([length, 4-byte int32])([data]) 

Так простые типы данных начинаются с кодом ASCII маркера, как «Я» для 32-битного междунар, 'T' для true, 'Z' для null, 'S' для строки и так далее.

Формат разработан с учетом требований к быстрому считыванию, поскольку все структуры данных имеют префикс их размера, поэтому нет сканирования для последовательностей с нулевым завершением.

Например, чтение строки, которая может быть отграничена, как это ([] -chars только для целей иллюстрации, они не записаны в формате)

[S][512][this is a really long 512-byte UTF-8 string....] 

Вы видели бы «S» , включите его для обработки строки, см. 4-байтовое целое, которое следует за ним «512», и знайте, что вы можете просто захватить в одном фрагменте следующие 512 байт и декодировать их обратно в строку.

Аналогично числовые значения выписываются без значения длины, чтобы быть более компактными, поскольку их тип (байты, int32, int64, double) определяет длину байтов (1, 4, 8 и 8. соответственно). для сколь угодно больших чисел, которые чрезвычайно переносимы, даже на платформах, которые их не поддерживают).

В среднем вы должны увидеть уменьшение размера примерно на 30% с помощью хорошо сбалансированного объекта JSON (много смешанных типов). Если вы хотите точно знать, как некоторые структуры сжимают или не сжимают, вы можете проверить раздел Size Requirements, чтобы получить представление.

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

Я проверил ядро ​​Input/OutputStream implementations для чтения/записи формата в GitHub сегодня. На этой неделе я буду проверять общее отображение объектов на основе отражения.

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

Если у вас есть конкретные вопросы, такие как спецификация (большой) спецификационного или числового формата для парных разрядов (IEEE 754), все это описано в спецификации или просто спросите меня.

Надеюсь, что это поможет!

+1

Это замечательно! Разбор тривиально. Скорость высокая. Размер очень хороший. И представление можно понять с помощью 'tcpdump' (в отличие от [varints] protobuf (https://developers.google.com/protocol-buffers/docs/encoding#varints)). В простой шестнадцатеричной системе 300 - это '0x012C'; в UBJ, '0x69012C' (поскольку' 0x69' - ascii 'i'); в protobuf, '0xAC02 == 1010 1100 0000 0010'. Protobuf становится еще сложнее (и медленнее) анализировать, если у вас есть отрицательные числа. Protobuf не сжимает строки или плавает, поэтому, если у вас много маленьких целых чисел, размер аналогичен, но UBJ работает быстро, а его синтаксический анализатор прост. – cdunn2001

+0

Любые опубликованные тесты, цифры по скорости? _Everything_ быстро разбирается в эти дни; вы должны сравнивать реализации, чтобы иметь представление о реальной скорости. – StaxMan

2

Другой альтернативой, который следует учитывать в наши дни, является CBOR (RFC 7049), который имеет явно совместимую с JSON модель с большой гибкостью. Он стабилен и соответствует вашей стандартной квалификации, и, очевидно, он много думал о нем.

+0

Очень приятно видеть настоящий стандарт. Спасибо за предложение! – Brad

Смежные вопросы