Récemment, j'ai trouvé MessagePack , un format de sérialisation binaire alternatif aux tampons de protocole de Google et JSON qui surpasse également les deux.
Il existe également le format de sérialisation BSON utilisé par MongoDB pour stocker des données.
Quelqu'un peut-il expliquer les différences et les inconvénients / avantages de BSON par rapport à MessagePack ?
Juste pour compléter la liste des formats de sérialisation binaires performants: il existe également des Gobs qui vont succéder aux Protocol Buffers de Google . Cependant, contrairement à tous les autres formats mentionnés, ceux-ci ne sont pas indépendants du langage et reposent sur la réflexion intégrée de Go, il existe également des bibliothèques Gobs pour au moins un autre langage que Go.
Réponses:
// Veuillez noter que je suis l'auteur de MessagePack. Cette réponse peut être biaisée.
Conception de format
Compatibilité avec JSON
Malgré son nom, la compatibilité de BSON avec JSON n'est pas aussi bonne que MessagePack.
BSON a des types spéciaux comme "ObjectId", "Min key", "UUID" ou "MD5" (je pense que ces types sont requis par MongoDB). Ces types ne sont pas compatibles avec JSON. Cela signifie que certaines informations de type peuvent être perdues lorsque vous convertissez des objets de BSON en JSON, mais bien sûr uniquement lorsque ces types spéciaux sont dans la source BSON. Il peut être désavantageux d'utiliser à la fois JSON et BSON dans un seul service.
MessagePack est conçu pour être converti de manière transparente de / vers JSON.
MessagePack est plus petit que BSON
Le format de MessagePack est moins détaillé que BSON. En conséquence, MessagePack peut sérialiser des objets plus petits que BSON.
Par exemple, une simple carte {"a": 1, "b": 2} est sérialisée en 7 octets avec MessagePack, tandis que BSON utilise 19 octets.
BSON prend en charge la mise à jour sur place
Avec BSON, vous pouvez modifier une partie de l'objet stocké sans re-sérialiser l'ensemble de l'objet. Supposons qu'une carte {"a": 1, "b": 2} soit stockée dans un fichier et que vous souhaitiez mettre à jour la valeur de "a" de 1 à 2000.
Avec MessagePack, 1 utilise seulement 1 octet mais 2000 utilise 3 octets. Donc "b" doit être reculé de 2 octets, tandis que "b" n'est pas modifié.
Avec BSON, 1 et 2000 utilisent 5 octets. En raison de cette verbosité, vous n'avez pas à déplacer "b".
MessagePack a RPC
MessagePack, Protocol Buffers, Thrift et Avro prennent en charge RPC. Mais BSON ne le fait pas.
Ces différences impliquent que MessagePack est à l'origine conçu pour la communication réseau tandis que BSON est conçu pour les stockages.
Implémentation et conception d'API
MessagePack a des API de vérification de type (Java, C ++ et D)
MessagePack prend en charge la saisie statique.
Le typage dynamique utilisé avec JSON ou BSON est utile pour les langages dynamiques comme Ruby, Python ou JavaScript. Mais gênant pour les langages statiques. Vous devez écrire des codes de vérification de type ennuyeux.
MessagePack fournit une API de vérification de type. Il convertit les objets typés dynamiquement en objets typés statiquement. Voici un exemple simple (C ++):
MessagePack a IDL
Il est lié à l'API de vérification de type, MessagePack prend en charge IDL. (la spécification est disponible sur: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Protocol Buffers et Thrift nécessitent IDL (ne prennent pas en charge le typage dynamique) et fournissent une implémentation IDL plus mature.
MessagePack a une API de streaming (Ruby, Python, Java, C ++, ...)
MessagePack prend en charge les désérialiseurs de streaming. Cette fonction est utile pour la communication réseau. Voici un exemple (Ruby):
la source
Je sais que cette question est un peu datée à ce stade ... Je pense qu'il est très important de mentionner que cela dépend de ce à quoi ressemble votre environnement client / serveur.
Si vous passez des octets plusieurs fois sans inspection, par exemple avec un système de file d'attente de messages ou des entrées de journal en streaming sur disque, vous préférerez peut-être un codage binaire pour souligner la taille compacte. Sinon, c'est un problème au cas par cas avec différents environnements.
Certains environnements peuvent avoir une sérialisation et une désérialisation très rapides vers / depuis msgpack / protobuf, d'autres pas tellement. En général, plus le langage / environnement est de bas niveau, meilleure sera la sérialisation binaire. Dans les langages de niveau supérieur (node.js, .Net, JVM), vous verrez souvent que la sérialisation JSON est en fait plus rapide. La question est alors de savoir si la surcharge de votre réseau est plus ou moins contrainte que votre mémoire / processeur?
En ce qui concerne msgpack vs bson vs tampons de protocole ... msgpack est le moins d'octets du groupe, les tampons de protocole étant à peu près les mêmes. BSON définit des types natifs plus larges que les deux autres, et peut être une meilleure correspondance avec votre mode objet, mais cela le rend plus verbeux. Les tampons de protocole ont l'avantage d'être conçus pour diffuser ... ce qui en fait un format plus naturel pour un format de transfert / stockage binaire.
Personnellement, je pencherais vers la transparence qu'offre directement JSON, à moins qu'il n'y ait un besoin clair de trafic plus léger. Sur HTTP avec des données gzippées, la différence de surcharge du réseau est encore moins un problème entre les formats.
la source
Un test rapide montre que JSON minifié est désérialisé plus rapidement que MessagePack binaire. Dans les tests, Article.json est un JSON minifié de 550 Ko, Article.mpack en est une version MP de 420 Ko. Cela peut bien sûr être un problème de mise en œuvre.
MessagePack:
JSON:
Les temps sont donc:
L'espace est donc économisé, mais plus rapidement? Non.
Versions testées:
la source
simplejson
2.6.2 prend 66,7 secondes etmsgpack
0.2.2 ne prend que 28,8.Une différence clé non encore mentionnée est que BSON contient des informations de taille en octets pour l'ensemble du document et d'autres sous-documents imbriqués.
Cela présente deux avantages majeurs pour les environnements restreints (par exemple embarqués) où la taille et les performances sont importantes.
la source
J'ai fait un benchmark rapide pour comparer la vitesse d'encodage et de décodage de MessagePack vs BSON. BSON est au moins plus rapide si vous avez de grands tableaux binaires:
Utilisation de C # Newtonsoft.Json et MessagePack par neuecc:
la source
Eh bien, comme l'auteur l'a dit, MessagePack est à l'origine conçu pour la communication réseau tandis que BSON est conçu pour les stockages.
MessagePack est compact tandis que BSON est verbeux. MessagePack est conçu pour être peu encombrant tandis que BSON est conçu pour CURD (time-efficient).
Plus important encore, le système de type de MessagePack (préfixe) suit le codage Huffman, ici j'ai dessiné un arbre Huffman de MessagePack (cliquez sur le lien pour voir l'image) :
la source