Статья является вольным переводом информации предоставленной на официальном сайте.
JSON является широко распространённым и популярным форматом для обмена данными. Его изящность, простота обработки и относительно богатая система типов стали естественным выбором для многих разработчиков, которым необходимо быстро и просто сохранять или случайным образом передавать данные между системами.
К сожалению, процесс упаковки и распаковки родных языку программирования структур с использованием текстового представления данных, пригодного для передачи по сети, имеет ощутимые затраты по ресурсам. В высоконагруженных системах избежание этапа обработки текста формата JSON может привести к более высоким, лучшим показателям обработки информации по времени и уменьшению хранимых данных по размеру.
Для достижения лучших результатов в таких случаях становится полезным использование двоичного формата JSON.
Попытки сделать использование JSON более скоростным, быстрым с помощью двоичных спецификаций, таких, как BSON, BJSON или Smile, существуют, но они терпят неудачу по двум причинам:
Например, BSON определяет типы данных для регулярных выражений, блоков JavaScript кода и других конструкций, у которых нет соответственного типа данных в JSON. BJSON тоже определяет свои типы данных, оставляя широкие возможности для ошибок, связанных с интерпретацией типов в двух разных реализациях. Smile определяет более сложные типы данных, правила генерирования и разбора, чтобы эффективно использовать место.
Все существующие двоичные спецификации JSON страдают от проблем несовместимости и сложности реализации, что естественным образом губит главное достоинство JSON, сделавшее его столь популярным, — простоту.
Простота JSON позволила создать реализации на различных языках программирования и сделала его удобным и понятным сразу для всех, кто использует ваши данные непосредственно.
Любая успешная спецификация двоичного JSON должна перенять эти свойства, чтобы быть действительного полезной для сообщества в целом.
Сжатие JSON может быть лучшим решением, чем использование двоичных форматов. Но тут есть две проблемы:
Получается, что размер передаваемых данных может быть уменьшен в среднем на 75%, но при этом сильно возрастут накладные расходы по обработке.
Universal Binary JSON спецификация спроектирована исключительно на принципах полной совместимости с JSON, простоты, скорости работы и доступности для понимания. Чтение и запись в данном формате носят тривиальный характер. Как побочный эффект — уменьшение пространства, занимаемого данными, в среднем на 30%.
Общий вид единственной структуры байтов в спецификации, используемой для описания всех поддерживаемых типов
Поля length и data используются или не используются в зависимости от типа данных. Например, тип 32 разрядное целое имеет стандартный размер в 4 байта. Для записи значения этого типа понадобится 1 байт под указание типа и 4 байта под само значение. В данном случае поле length не используется по причине ненадобности.
Благодаря такому представлению информации достигаются поставленные цели.
Спецификацией Universal Binary JSON поддерживаются:
Важные особенности: значения числовых типов записываются в порядке байтов от старшего к младшему (Big-Endian) и основная кодировка текстовой информации — UTF-8.
Реализации на других языках программирования будут доступны по мере появления по этой ссылке.
P.S.: Автор спецификации и реализации на Java, Riyad Kalla и я, автор статьи и реализации на C#, будем рады любому вашему участию в процессе работы над спецификацией.
Введение
JSON является широко распространённым и популярным форматом для обмена данными. Его изящность, простота обработки и относительно богатая система типов стали естественным выбором для многих разработчиков, которым необходимо быстро и просто сохранять или случайным образом передавать данные между системами.
К сожалению, процесс упаковки и распаковки родных языку программирования структур с использованием текстового представления данных, пригодного для передачи по сети, имеет ощутимые затраты по ресурсам. В высоконагруженных системах избежание этапа обработки текста формата JSON может привести к более высоким, лучшим показателям обработки информации по времени и уменьшению хранимых данных по размеру.
Для достижения лучших результатов в таких случаях становится полезным использование двоичного формата JSON.
Почему?
Попытки сделать использование JSON более скоростным, быстрым с помощью двоичных спецификаций, таких, как BSON, BJSON или Smile, существуют, но они терпят неудачу по двум причинам:
- Внутренние типы данных. Использование внутренних типов данных, исключительно присущих только двоичным форматам и изначально не включённых в стандарт JSON, делает непригодными для широкого использования вышеуказанные спецификации, так как, в зависимости от реализации, каждый такой тип может интерпретироваться по разному.
- Сложность реализации. Одни форматы позволяют добиться более высокой производительности, а другие — более компактного представления за счёт более сложной, запутанной спецификации. Что, в свою очередь, замедляет или делает невозможных их распространение и внедрение. Простота использования — двигатель успеха JSON.
Например, BSON определяет типы данных для регулярных выражений, блоков JavaScript кода и других конструкций, у которых нет соответственного типа данных в JSON. BJSON тоже определяет свои типы данных, оставляя широкие возможности для ошибок, связанных с интерпретацией типов в двух разных реализациях. Smile определяет более сложные типы данных, правила генерирования и разбора, чтобы эффективно использовать место.
Все существующие двоичные спецификации JSON страдают от проблем несовместимости и сложности реализации, что естественным образом губит главное достоинство JSON, сделавшее его столь популярным, — простоту.
Простота JSON позволила создать реализации на различных языках программирования и сделала его удобным и понятным сразу для всех, кто использует ваши данные непосредственно.
Любая успешная спецификация двоичного JSON должна перенять эти свойства, чтобы быть действительного полезной для сообщества в целом.
Почему не JSON+gzip?
Сжатие JSON может быть лучшим решением, чем использование двоичных форматов. Но тут есть две проблемы:
- На 50% падает скорость работы с данными.
- Нет возможности исследовать данные и работать с ними напрямую.
Получается, что размер передаваемых данных может быть уменьшен в среднем на 75%, но при этом сильно возрастут накладные расходы по обработке.
Цели
Universal Binary JSON спецификация спроектирована исключительно на принципах полной совместимости с JSON, простоты, скорости работы и доступности для понимания. Чтение и запись в данном формате носят тривиальный характер. Как побочный эффект — уменьшение пространства, занимаемого данными, в среднем на 30%.
- Полная совместимость. 100% совместимость с JSON и исключительное использование типов данных, поддерживаемых всеми современными языками программирования. Это позволяет эффективно преобразовывать данные между JSON и Universal Binary JSON без использования разработчиками замысловатых структур данных, которые могут и не поддерживаться языком программирования.
- Простота использования. Достигается за счёт того, что за основу взята спецификация JSON и используется всего лишь одна двоичная структура для рационального описания типов. Благодаря этому получаем доступность и простоту понимания разработчиками.
- Скорость и эффективность. Мотивация использования двоичных форматов заключается в скорости и эффективности разбора данных. При этом, как побочный эффект, снижение потребления пространства на 30%.
Формат данных
Общий вид единственной структуры байтов в спецификации, используемой для описания всех поддерживаемых типов
[type, 1-byte char]([length, 1 or 4-byte integer])([data])
- type — 1 байт, символ из ASCII. Используется для указания типа данных, что следуют за ним.
- length (опционально) — 1 или 4 байта (целое значение) в зависимости от длины или размера объекта. Для массива — его длина. Для объекта — количество пар Ключ/Значение. Если длина или количество элементов от 0 и до 254 включительно, то используется 1 байт. Это поле со значением 255 зарезервировано для объектов и массивов неизвестной длины.
- data (опционально) — последовательность байтов, непосредственно представляющая собой данные объекта.
Поля length и data используются или не используются в зависимости от типа данных. Например, тип 32 разрядное целое имеет стандартный размер в 4 байта. Для записи значения этого типа понадобится 1 байт под указание типа и 4 байта под само значение. В данном случае поле length не используется по причине ненадобности.
Благодаря такому представлению информации достигаются поставленные цели.
Возможности
Спецификацией Universal Binary JSON поддерживаются:
- основные типы данных
- массивы
- объекты
- целые числа, массивы и объекты неизвестной длины или размера
- потоковая передача данных
Важные особенности: значения числовых типов записываются в порядке байтов от старшего к младшему (Big-Endian) и основная кодировка текстовой информации — UTF-8.
Сообщество
- Официальный сайт спецификации UBJSON — Universal Binary JSON
- Принимали участие и обсуждали
- Реализация на Java — Universal Binary JSON Java Library
- Простая реализация на C# — Ubjson.NET
Реализации на других языках программирования будут доступны по мере появления по этой ссылке.
P.S.: Автор спецификации и реализации на Java, Riyad Kalla и я, автор статьи и реализации на C#, будем рады любому вашему участию в процессе работы над спецификацией.