// 私は MessagePack の作成者です。この回答は偏っている可能性があります。
フォーマット設計
JSON との互換性
その名前にもかかわらず、BSON の JSON との互換性は MessagePack に比べてあまり良くありません。
BSON には、"ObjectId"、"Min key"、"UUID"、"MD5" などの特殊な型があります (MongoDB ではこれらの型が必要だと思います)。これらの型は JSON と互換性がありません。つまり、オブジェクトを BSON から JSON に変換すると、一部の型情報が失われる可能性がありますが、もちろん、これらの特殊な型が BSON ソースにある場合に限ります。1 つのサービスで JSON と BSON の両方を使用すると、不利になる可能性があります。
MessagePack は、JSON との間で透過的に変換されるように設計されています。
MessagePack は BSON より小さい
MessagePack の形式は、BSON よりも冗長ではありません。その結果、MessagePack は BSON より小さいオブジェクトをシリアル化できます。
たとえば、単純なマップ {"a":1, "b":2} は MessagePack では 7 バイトでシリアル化されますが、BSON では 19 バイトが使用されます。
BSON はインプレース更新をサポートします
BSON を使用すると、オブジェクト全体を再シリアル化せずに、格納されたオブジェクトの一部を変更できます。マップ {"a":1, "b":2} がファイルに保存されていて、"a" の値を 1 から 2000 に更新したいとします。
MessagePack では、1 は 1 バイトしか使用しませんが、2000 は 3 バイトを使用します。したがって、「b」は 2 バイト後方に移動する必要がありますが、「b」は変更されません。
BSON では、1 と 2000 の両方が 5 バイトを使用します。この冗長性のため、「b」を移動する必要はありません。
MessagePack には RPC があります
MessagePack、Protocol Buffers、Thrift、および Avro は RPC をサポートしています。しかし、BSON はそうではありません。
これらの違いは、BSON がストレージ用に設計されているのに対し、MessagePack はもともとネットワーク通信用に設計されていることを意味します。
実装と API の設計
MessagePack には型チェック API (Java、C++、および D) があります。
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>();
}
MessagePack には IDL があります
これは型チェック API に関連しており、MessagePack は IDL をサポートしています。(仕様はhttp://wiki.msgpack.org/display/MSGPACK/Design+of+IDLから入手できます)
Protocol Buffers と Thrift は IDL を必要とし (動的型付けをサポートしていません)、より成熟した IDL 実装を提供します。
MessagePack にはストリーミング API (Ruby、Python、Java、C++ など) があります。
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
}