Недавно я обнаружил MessagePack , альтернативный двоичный формат сериализации для буферов протокола Google и JSON, который также превосходит оба.
Также есть формат сериализации BSON , который используется MongoDB для хранения данных.
Может кто-нибудь рассказать о различиях и недостатках BSON по сравнению с MessagePack ?
Просто, чтобы завершить список эффективных форматов двоичной сериализации: есть также Гобы, которые станут преемниками протокольных буферов Google . Однако, в отличие от всех других упомянутых форматов, которые не зависят от языка и полагаются на встроенное отражение Go, есть библиотеки Gobs, по крайней мере, на другом языке, чем Go.
Ответы:
// Обратите внимание, что я автор MessagePack. Этот ответ может быть предвзятым.
Формат дизайна
Совместимость с JSON
Несмотря на свое название, совместимость BSON с JSON не так хороша по сравнению с MessagePack.
BSON имеет специальные типы, такие как «ObjectId», «Min key», «UUID» или «MD5» (я думаю, что эти типы требуются MongoDB). Эти типы не совместимы с JSON. Это означает, что некоторая информация о типах может быть потеряна при преобразовании объектов из BSON в JSON, но, конечно, только когда эти специальные типы находятся в источнике BSON. Недостатком может быть использование JSON и BSON в одном сервисе.
MessagePack предназначен для прозрачного преобразования из / в JSON.
Пакет сообщений меньше, чем BSON
Формат MessagePack менее многословен, чем BSON. В результате MessagePack может сериализовать объекты меньше BSON.
Например, простая карта {"a": 1, "b": 2} сериализуется в 7 байтов с помощью MessagePack, а BSON использует 19 байтов.
BSON поддерживает обновление на месте
С помощью BSON вы можете изменить часть сохраненного объекта без повторной сериализации всего объекта. Предположим, карта {"a": 1, "b": 2} хранится в файле, и вы хотите обновить значение "a" с 1 до 2000.
В MessagePack 1 использует только 1 байт, а в 2000 - 3 байта. Таким образом, «b» должен быть перемещен назад на 2 байта, в то время как «b» не изменяется.
С BSON и 1, и 2000 используют 5 байтов. Из-за этого многословия вам не нужно двигать «б».
MessagePack имеет RPC
MessagePack, Protocol Buffers, Thrift и Avro поддерживают RPC. Но BSON нет.
Эти различия подразумевают, что MessagePack изначально предназначен для сетевого взаимодействия, а BSON - для хранилищ.
Реализация и дизайн API
MessagePack имеет API для проверки типов (Java, C ++ и D)
MessagePack поддерживает статическую типизацию.
Динамическая типизация, используемая с JSON или BSON, полезна для динамических языков, таких как Ruby, Python или JavaScript. Но хлопотно для статических языков. Вы должны написать скучные коды проверки типов.
MessagePack предоставляет API для проверки типов. Он преобразует объекты динамического типа в объекты статического типа. Вот простой пример (C ++):
MessagePack имеет IDL
Это связано с API проверки типов, MessagePack поддерживает IDL. (спецификация доступна по адресу : http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Буферы протокола и Thrift требуют IDL (не поддерживают динамическую типизацию) и обеспечивают более зрелую реализацию IDL.
MessagePack имеет потоковый API (Ruby, Python, Java, C ++, ...)
MessagePack поддерживает потоковые десериализаторы. Эта функция полезна для сетевого общения. Вот пример (Ruby):
источник
Я знаю, что этот вопрос немного устарел на данный момент ... Я думаю, что очень важно упомянуть, что это зависит от того, как выглядит ваша клиент-серверная среда.
Если вы передаете байты несколько раз без проверки, например, с помощью системы очереди сообщений или потоковой передачи записей журнала на диск, тогда вы можете предпочесть двоичную кодировку, чтобы подчеркнуть компактный размер. В противном случае это индивидуальная проблема с различными средами.
Некоторые среды могут иметь очень быструю сериализацию и десериализацию в / из msgpack / protobuf, другие не так много. В целом, чем ниже уровень языка / среды, тем лучше будет двоичная сериализация. В языках более высокого уровня (node.js, .Net, JVM) вы часто видите, что сериализация JSON на самом деле быстрее. Тогда возникает вопрос, является ли нагрузка на вашу сеть более или менее ограниченной, чем ваша память / процессор?
Что касается msgpack против bson против протокольных буферов ... msgpack - это наименьшее количество байтов в группе, причем протокольные буферы примерно одинаковы. BSON определяет более широкие собственные типы, чем два других, и может лучше соответствовать вашему объектному режиму, но это делает его более подробным. Буферы протокола имеют то преимущество, что они предназначены для потоковой передачи ... что делает их более естественным форматом для двоичного формата передачи / хранения.
Лично я бы склонялся к прозрачности, которую предлагает JSON напрямую, если только нет явной необходимости в меньшем трафике. По протоколу HTTP с сжатыми данными разница в затратах сети является еще меньшей проблемой между форматами.
источник
Быстрый тест показывает, что минимизированный JSON десериализуется быстрее, чем двоичный MessagePack. В тестах Article.json - это минимизированный JSON 550 Кбайт, Article.mpack - это MP-версия 420 Кбайт. Может быть проблема реализации, конечно.
MessagePack:
JSON:
Итак, времена такие:
Так что место сэкономлено, но быстрее? Нет.
Протестированные версии:
источник
simplejson
2.6.2 занимает 66,7 секунды, аmsgpack
0.2.2 - всего 28,8.Ключевое отличие, еще не упомянутое, состоит в том, что BSON содержит информацию о размере в байтах для всего документа и последующих вложенных поддокументов.
Это имеет два основных преимущества для ограниченных сред (например, встроенных), где важны размер и производительность.
источник
Я сделал быстрый тест для сравнения скорости кодирования и декодирования MessagePack и BSON. BSON быстрее, по крайней мере, если у вас большие двоичные массивы:
Использование C # Newtonsoft.Json и MessagePack от neuecc:
источник
Ну, как сказал автор, MessagePack изначально предназначен для сетевого взаимодействия, а BSON - для хранилищ.
MessagePack компактен, а BSON многословен. MessagePack предназначен для экономии пространства, а BSON разработан для CURD (экономия времени).
Самое главное, что система типов MessagePack (префикс) соответствует кодировке Хаффмана, здесь я нарисовал дерево Хаффмана для MessagePack (нажмите на ссылку, чтобы увидеть изображение):
источник