最近,我找到了 MessagePack ,这是Google的Protocol Buffers和JSON的另一种二进制序列化格式,它的性能也优于两者。
还有MongoDB用于存储数据的BSON序列化格式。
有人可以详细说明BSON与MessagePack的区别和缺点吗?
只是为了完成高性能二进制序列化格式的列表:还有Gobs,它将成为Google Protocol Buffer 的后继者。但是,与所有其他提到的格式相反,这些格式不是语言不可知的,它们依赖Go's built-in reflection。此外,还有Gobs库,它们至少依赖于Go以外的其他语言。
最佳答案
//请注意,我是MessagePack的作者。这个答案可能有偏见。
格式设计
尽管名称如此,但BSON与JSON的兼容性与MessagePack相比并不是很好。
BSON具有特殊类型,例如“ObjectId”,“Min key”,“UUID”或“MD5”(我认为MongoDB需要这些类型)。这些类型与JSON不兼容。这意味着当您将对象从BSON转换为JSON时,某些类型信息可能会丢失,但是当然只有当这些特殊类型在BSON源中时,这些信息才会丢失。在单个服务中同时使用JSON和BSON可能是不利的。
MessagePack旨在从JSON透明转换。
MessagePack的格式不如BSON冗长。结果,MessagePack可以序列化小于BSON的对象。
例如,一个简单的映射{“a”:1,“b”:2}使用MessagePack序列化为7个字节,而BSON使用19个字节。
使用BSON,您可以修改存储对象的一部分,而无需重新序列化整个对象。假设将映射{{a“:1,” b“:2}存储在文件中,并且您想将” a“的值从1更新为2000。
对于MessagePack,1仅使用1个字节,而2000使用3个字节。因此,“b”必须向后移2个字节,而“b”没有被修改。
使用BSON,1和2000都使用5个字节。由于这种冗长,您不必移动“b”。
MessagePack, Protocol Buffer ,节流和Avro支持RPC。但是BSON没有。
这些差异意味着MessagePack最初是为网络通信而设计的,而BSON是为存储而设计的。
实现和API设计
MessagePack支持静态键入。
与JSON或BSON一起使用的动态类型对于动态语言(例如Ruby,Python或JavaScript)非常有用。但是麻烦的是静态语言。您必须编写无聊的类型检查代码。
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>();
}
它与类型检查API有关,MessagePack支持IDL。 (可以从http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL获得规范)
Protocol Buffer 和节流协议(protocol)需要IDL(不支持动态类型),并提供更成熟的IDL实现。
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
}
关于serialization - 性能实体序列化:BSON与MessagePack(对比JSON),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6355497/