Статьи

Сравнение сериализации данных: JSON, YAML, BSON, MessagePack

Сравнение сериализации данных

JSON является стандартом де-факто для обмена данными в сети, но у него есть свои недостатки, и есть другие форматы, которые могут быть более подходящими для определенных сценариев. Я сравню плюсы и минусы альтернатив, в том числе простоту использования и производительность.

Примечание: здесь я не буду описывать детали реализации, но если вы программист на Ruby, ознакомьтесь с этой статьей , в которой Dhaivat пишет о реализации некоторых форматов сериализации в Ruby.

Что такое сериализация данных

Согласно Википедии , сериализация это:

процесс преобразования структур данных или состояния объекта в формат, который может быть сохранен (например, в буфере файла или памяти, или передан по каналу сетевого подключения) и позже восстановлен в той же или другой компьютерной среде.

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

имя фамилия дата рождения прозвище инструменты
Уильям двор замка 1962 Эксл Роуз вокал, фортепиано
Сол Гудзон 1965 Рассечение гитара

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

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

Вкратце: сериализация данных — это некий универсальный формат, который можно легко использовать в разных приложениях.

Форматы

JSON

Логотип JSON

JSON (JavaScript Object Notation) — это легкий формат обмена данными. Людям легко читать и писать; машины легко разбираются и генерируются.

JSON является наиболее распространенным форматом сериализации данных и имеет следующие особенности:

  • (В основном) читаемый человеком код : даже если код был скрыт или уменьшен , вы всегда можете сделать отступ с помощью таких инструментов, как JSONLint, и снова сделать его читаемым.
  • Очень простая и понятная спецификация : сводка всей спецификации помещается на одной странице ( как показано на сайте JSON ).
  • Широкая поддержка : не только каждый язык программирования или IDE поставляется с поддержкой JSON, но также многие API веб-сервисов предлагают JSON в качестве средства обмена данными.
  • Как подмножество JavaScript, он поддерживает следующие типы данных JavaScript :
    • строка
    • число
    • объект
    • массив
    • truefalse
    • null

Вот как будет выглядеть наша предыдущая электронная таблица после сериализации в JSON:

 [
  {
    "name": "William",
    "last name": "Bailey",
    "dob": 1962,
    "nickname": "Axl Rose",
    "instruments": [
      "vocals",
      "piano"
    ]
  },
  {
    "name": "Saul",
    "last name": "Hudson",
    "dob": 1965,
    "nickname": "Slash",
    "instruments": [
      "guitar"
    ]
  }
]

BSON

Логотип BSON

BSON, сокращение от Binary JSON, представляет собой двоичную сериализацию JSON-подобных документов. … Он также содержит расширения, которые позволяют представлять типы данных, которые не являются частью спецификации JSON.

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

Он имеет следующие особенности:

  • удобное хранение двоичной информации : лучше подходит для обмена изображениями и вложениями
  • предназначен для быстрой манипуляции в памяти
  • простая спецификация : как и JSON, BSON имеет очень короткую и простую спецификацию
  • первичное представление данных для MongoDB : BSON разработан так, чтобы его можно было легко обойти
  • дополнительные типы данных :
    • double (64-битное число IEEE 754 с плавающей запятой)
    • дата (целое число миллисекунд с начала эпохи Unix)
    • байтовый массив (двоичные данные)
    • Объект BSON и массив BSON
    • Код JavaScript
    • MD5 двоичные данные
    • регулярные выражения

MessagePack

MessagePack

Это как JSON. Но быстро и мало.

MessagePack (также msgpack) — еще один двоичный формат для сериализации. Не так хорошо известен, как BSON, но стоит посмотреть.

Среди его особенностей:

  • предназначен для эффективной передачи по проводам
  • лучшая JSON-совместимость, чем BSON : как объясняет Садаюки Фурухаси в этом посте переполнения стека
  • меньше, чем BSON : имеет меньшие издержки, чем BSON, и может сериализовать меньшие объекты большую часть времени
  • проверка типов : поддерживает статическую типизацию
  • потоковый API : поддержка потоковых десериализаторов, что полезно для сетевого взаимодействия.

YAML

YAML: YAML не является языком разметки.
Что это такое: YAML — это удобный для людей стандарт сериализации данных для всех языков программирования.

Возвращаясь к текстовым форматам, YAML является альтернативой JSON:

  • (действительно) читаемый человеком код : YAML настолько читабелен, что даже его содержимое на первой странице отображается в YAML, чтобы подчеркнуть это
  • компактный код : отступ для пробелов используется для обозначения структуры, без кавычек и скобок
  • синтаксис для реляционных данных : разрешить внутренние ссылки с якорями ( &*
  • особенно подходит для просмотра / редактирования структур данных : таких как файлы конфигурации, дамп во время отладки и заголовки документов
  • богатый набор независимых от языка типов :
    • коллекции :
      • неупорядоченный набор ключей ( !!map
      • упорядоченная последовательность клавиш ( !!omap
      • упорядоченная последовательность клавиш ( !!pairs
      • неупорядоченный набор неравных значений ( !!set
      • последовательность произвольных значений ( !!seq
    • скалярные типы :
      • нулевые значения ( ~null
      • десятичные ( 12340x4D202333
      • фиксированное ( 1_230.1512.3015e+02
      • бесконечность ( .inf-.Inf.NAN
      • true ( YtrueYesONnFALSENooff
      • бинарный ( !!binarybase64
      • временные метки ( !!timestamp

Вот как выглядит наша маленькая электронная таблица при сериализации в YAML:

 - name: William
  last name: Bailey
  dob: 1962
  nickname: Axl Rose
  instruments:
    - vocals
    - piano

- name: Saul
  last name: Hudson
  dob: 1965
  nickname: Slash
  instruments:
    - guitar

Другие форматы

Существует ряд других форматов для сериализации, таких как протокольные буферы (protobuf, также двоичный), которые я (довольно дискреционно) не учел. Если вы просто хотите узнать все возможные форматы, посмотрите и сравните форматы сериализации данных в Википедии.

… HDF5?

Логотип HDF5

Мы получим немного не по теме здесь, но только немного. Иерархический формат данных версии 5 ( HDF5 ) на самом деле не для сериализации, а скорее для хранения, и он штурмом берет науку о данных и другие отрасли . Это очень быстрый и универсальный формат, который можно использовать не только для хранения ряда структур данных, но даже в качестве замены реляционных баз данных.

Чтобы завершить этот перерыв, просто отметим, что если вы используете двоичные форматы, такие как BSON и MessagePack для хранения / обмена большими объемами информации, вы, возможно, захотите взглянуть на HDF5.

Тесты и сравнения

Появляется закономерность: BSON может быть дороже, чем JSON при сериализации, но быстрее при десериализации; и MessagePack быстрее, чем оба в любой операции. Кроме того, из-за своих издержек и, несмотря на то, что они являются двоичным форматом, файлы BSON могут иногда быть больше, чем файлы JSON при хранении недвоичных данных. Некоторые ссылки для просмотра:

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

Замечания и комментарии

Как бы глупо это не звучало, BSON имеет преимущество в названии : люди автоматически связывают формат, разработанный MongoDB (BSON), со стандартом (JSON), которые не связаны друг с другом. Поэтому при поиске бинарной альтернативы для JSON вы можете также рассмотреть другие варианты.

Фактически, MessagePack, кажется, превосходит BSON во всех возможных аспектах: он быстрее, меньше и еще более совместим с JSON, чем BSON. (На самом деле, если вы уже работаете с JSON, MessagePack — это почти полная оптимизация.) Может быть, как «репортер» я должен быть более сбалансированным, но как разработчик, это не так уж и сложно.

Тем не менее, BSON — это формат MongoDB для хранения и представления данных, поэтому, если вы работаете с этой базой данных NoSQL, это повод придерживаться ее.

Конечно, сериализация — это не только хранение двоичных данных. По общему признанию, JSON имеет в виду другую цель — быть «читабельным для человека» . Но не нужно много усилий, чтобы заметить, что YAML справляется с этим значительно лучше.

Тем не менее, спецификация YAML ужасно велика , особенно по сравнению с JSON. Но, возможно, так и должно быть, поскольку в нем больше типов данных и функций.

С другой стороны, нельзя игнорировать тот факт, что простота JSON сыграла ключевую роль в его принятии по сравнению с другими форматами сериализации. Он опирается на уже существующий широко распространенный язык JavaScript, и, если вы знаете JS или знакомы с ним (а если вы работаете в сфере веб-разработки), то вы уже знаете JSON.

Тогда почему бы не принять YAML, как сейчас ? Во многих случаях это не так просто. В JSON все еще есть место для веб-API, так как вы можете легко встраивать код JSON в HTTP-запросы (как для GET, как в URL-адресах, так и в POST, как при отправке формы): формат сообщит вам, если передача внезапно оборвалась , поскольку код будет автоматически отображаться как недействительный, что может быть не так в случае YAML и других конкурирующих форматов открытого текста. Кроме того, вам все равно придется взаимодействовать в тот или иной момент с API-интерфейсами на основе JSON и устаревшим кодом, и всегда сложно поддерживать два куска кода (методы JSON и YAML) для одной и той же цели (сериализация данных).

Но опять же, это отчасти те же самые аргументы, которые толкают нас назад и мешают нам внедрять более новые и более эффективные технологии (например, как Python 3 над Python 2). И я на минуту подумал, что мы, программисты и предприниматели, были новаторами, не так ли?