148 votes

Sérialisation d’entité performant : BSON vs MessagePack (vs JSON)

Récemment, j'ai trouvé MessagePack une alternative binaire format de sérialisation de Google Protocol Buffers et JSON qui a également surpasse à la fois.

Il ya aussi le BFILS format de sérialisation qui est utilisé par MongoDB pour le stockage des données.

Quelqu'un peut-il élaborer les différences et les dis-/adavantages de BFILS vs MessagePack?


Juste pour compléter la liste de performant formats de sérialisation binaire: Il y a aussi les Boules qui vont être le successeur de Google Protocol Buffers. Cependant à la différence de tous les autres éléments mentionnés formats de ceux qui sont pas indépendant de la langue et appuyer sur Go intégré dans la réflexion.

212voto

Sadayuki Furuhashi Points 1016

// S'il vous plaît noter que je suis l'auteur de MessagePack. Cette réponse peut être biaisée.

Format de conception

  1. La compatibilité avec JSON

    En dépit de son nom, BFILS assurer de la compatibilité avec JSON n'est pas très bonne en comparaison avec MessagePack.

    BFILS a des types comme "ObjectId", "Min", "UUID" ou "MD5" (je pense que ces types sont tenus par MongoDB). Ces types ne sont pas compatibles avec JSON. Il désigne un certain type d'informations sont perdues lors de la conversion des objets à partir de BFILS en JSON. Il peut être un inconvénient à l'utilisation à la fois JSON et BFILS dans un seul service.

    MessagePack est conçu pour être convertie à partir de/JSON.

  2. MessagePack est plus petit que BFILS

    MessagePack format est moins verbeux que BFILS. Comme le résultat, MessagePack pouvez sérialiser des objets plus petits que BFILS.

    Par exemple, une carte simple {"a":1, "b":2} est sérialisé dans 7 octets avec MessagePack, tandis que BFILS utilise 19 octets.

  3. BFILS prend en charge la mise à jour

    Avec BFILS, vous pouvez modifier une partie de l'objet stocké sans re-sérialisation d'ensemble de l'objet. Supposons qu'une carte {"a":1, "b":2} est stockée dans un fichier et que vous souhaitez mettre à jour la valeur de "a" à partir de 1 à 2000.

    Avec MessagePack, 1 utilise seulement 1 octet mais 2000 utilise 3 octets. Si "b" doit être déplacé vers l'arrière par 2 octets, alors que la "b" n'est pas modifié.

    Avec BFILS, à la fois 1 et 2000, l'utilisation de 5 octets. De ce fait le niveau de verbosité, vous n'avez pas à déplacer "b".

  4. MessagePack a RPC

    MessagePack, Protocole de Tampons, d'Épargne et d'Avro soutien de la RPC. Mais BFILS ne l'est pas.

Ces différences impliquent que MessagePack est à l'origine conçu pour la communication en réseau tout en BFILS est conçu pour les installations de stockage.

La mise en œuvre et de conception d'API

  1. MessagePack a la vérification de type Api (Java, C++ et D)

    MessagePack prend en charge statique-typage.

    Dynamique de frappe utilisé avec JSON ou BFILS sont utiles pour les langages dynamiques comme Ruby, Python ou JavaScript. Mais gênant pour les langages statiques. Vous devez écrire ennuyeux type de vérification des codes.

    MessagePack fournit la vérification de type API. Il convertit de façon dynamique les objets de type en statiquement typé objets. Voici un exemple simple (C++):

    #include <msgpack.hpp>
    
    class myclass {
    private:
        std::string str;
        std::vector<int> vec;
    public:
        // This macro enables this class to be serialized/deserialized
        MSGPACK_DEFINE(str, vec);
    };
    
    int main(void) {
        // serialize
        myclass m1 = ...;
    
        msgpack::sbuffer buffer;
        msgpack::pack(&buffer, m1);
    
        // deserialize
        msgpack::unpacked result;
        msgpack::unpack(&result, buffer.data(), buffer.size());
    
        // you get dynamically-typed object
        msgpack::object obj = result.get();
    
        // convert it to statically-typed object
        myclass m2 = obj.as<myclass>();
    }
    
  2. MessagePack a IDL

    C'est lié à la vérification de type API, MessagePack prend en charge IDL. (spécification est disponible à partir de: http://wiki.msgpack.org/display/MSGPACK/Design+de+IDL)

    Tampons de protocole d'Épargne et nécessitent IDL (ne supportent pas la dynamique de la frappe) et de fournir plus mature IDL mise en œuvre.

  3. MessagePack a streaming API (Ruby, Python, Java, C++, ...)

    MessagePack prend en charge la diffusion deserializers. Cette fonctionnalité est utile pour la communication réseau. Voici un exemple (Ruby):

    require 'msgpack'
    
    # write objects to stdout
    $stdout.write [1,2,3].to_msgpack
    $stdout.write [1,2,3].to_msgpack
    
    # read objects from stdin using streaming deserializer
    unpacker = MessagePack::Unpacker.new($stdin)
    # use iterator
    unpacker.each {|obj|
      p obj
    }
    

17voto

Tracker1 Points 6573

Je sais que cette question est un peu daté à ce point... je pense qu'il est très important de mentionner qu'il dépend de ce que votre environnement client/serveur.

Si vous êtes de passage octets à plusieurs reprises sans inspection, comme avec un message de système de file d'attente ou en streaming les entrées de journal sur le disque, puis vous peut très bien préférer un codage binaire pour souligner la taille compacte. Sinon c'est du cas par cas, un problème avec des environnements différents.

Certains environnements peuvent avoir très vite de sérialisation et de désérialisation vers/à partir de msgpack/protobuf, d'autres pas tellement. En général, le plus bas niveau de la langue et de l'environnement le mieux la sérialisation binaire de travail. Dans un langage de haut niveau (node.js, .Net, JVM) vous verrez souvent que la sérialisation JSON est effectivement plus rapide. La question devient alors est de votre réseau plus ou moins contraint que votre mémoire/cpu?

En ce qui concerne msgpack vs bfils vs protocol buffers... msgpack est le moins octets du groupe, protocol buffers être sur la même chose. BFILS définit de plusieurs grands types natifs que les deux autres, et peut-être mieux correspondre à votre mode de l'objet, mais cela le rend plus détaillé. Protocol buffers ont l'avantage d'être conçu pour les flux... ce qui en fait un de plus naturel pour le format d'un transfert binaire/format de stockage.

Personnellement, je pencherais vers la transparence que JSON offre directement, sauf s'il y a un besoin clair de trafic plus léger. Sur HTTP avec format de données, à la différence de la surcharge du réseau sont encore moins d'un problème entre les formats.

4voto

Test rapide montre compressée JSON désérialisé plus vite que le binaire MessagePack. Dans les essais Article.json est minimisé de 550ko JSON, Article.mpack est 420ko MP-version de celui-ci. Peut-être un problème de mise en oeuvre bien sûr.

MessagePack :

JSON :

Si les temps sont :

Donc l’espace est sauvé, mais plus rapide ? N °

Versions testées :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X