最近,我找到了MessagePack,这是Google协议缓冲区和JSON的另一种二进制序列化格式,它的性能也优于两者。

另外,MongoDB还使用了BSON序列化格式来存储数据。

有人可以详细说明BSON与MessagePack的区别和缺点吗?

只是为了完成高性能二进制序列化格式的列表:还有Gob,它们将成为Google协议缓冲区的后继者。但是,与所有其他提到的格式相反,这些格式不是语言不可知的,并且依赖于Go的内置反射,此外还有Gobs库,至少可以使用除Go之外的其他语言。

最佳答案

//请注意,我是MessagePack的作者。这个答案可能有偏见。

格式设计

  1. 与JSON的兼容性
  2. 尽管名称如此,但BSON与JSON的兼容性与MessagePack相比并不是很好。
  3. BSON具有特殊类型,例如“ ObjectId”,“ Min key”,“ UUID”或“ MD5”(我认为MongoDB需要这些类型)。这些类型与JSON不兼容。这意味着当您将对象从BSON转换为JSON时,某些类型信息可能会丢失,但是当然只有当这些特殊类型在BSON源中时,这些信息才会丢失。在单个服务中同时使用JSON和BSON可能是不利的。
  4. MessagePack旨在透明地从JSON转换为JSON。
  5. MessagePack小于BSON
  6. MessagePack的格式不如BSON冗长。结果,MessagePack可以序列化小于BSON的对象。
  7. 例如,一个简单的映射{“ a”:1,“ b”:2}使用MessagePack序列化为7个字节,而BSON使用19个字节。
  8. BSON支持就地更新
  9. 使用BSON,您可以修改存储的对象的一部分,而无需重新序列化整个对象。假设映射{{a“:1,” b“:2}存储在文件中,并且您想将” a“的值从1更新为2000。
  10. 对于MessagePack,1仅使用1个字节,而2000使用3个字节。因此,“ b”必须向后移2个字节,而“ b”没有被修改。
  11. 使用BSON,1和2000都使用5个字节。由于这种冗长,您不必移动“ b”。
  12. MessagePack具有RPC
  13. MessagePack,协议缓冲区,节流和Avro支持RPC。但是BSON没有。

这些差异意味着MessagePack最初是为网络通信而设计的,而BSON是为存储而设计的。

实施和API设计

  1. MessagePack具有类型检查API(Java,C ++和D)
  2. MessagePack支持静态键入。
  3. 与JSON或BSON一起使用的动态类型对于动态语言(例如Ruby,Python或JavaScript)很有用。但是麻烦的是静态语言。您必须编写无聊的类型检查代码。
  4. MessagePack提供了类型检查API。它将动态类型的对象转换为静态类型的对象。这是一个简单的示例(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>();
    }
  1. MessagePack具有IDL
  2. 它与类型检查API有关,MessagePack支持IDL。 (可以从以下网址获得规范:http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL)
  3. 协议缓冲区和节流协议需要IDL(不支持动态类型),并提供更成熟的IDL实现。
  4. MessagePack具有流API(Ruby,Python,Java,C ++等)
  5. MessagePack支持流式反序列化器。此功能对于网络通信很有用。这是一个示例(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
    }