Baru-baru ini saya menemukan MessagePack , format serialisasi biner alternatif untuk Protocol Buffer dan JSON Google yang juga mengungguli keduanya.
Juga ada format serialisasi BSON yang digunakan oleh MongoDB untuk menyimpan data.
Adakah yang bisa menjelaskan perbedaan dan keunggulan BSON vs MessagePack ?
Sekadar melengkapi daftar format serialisasi biner yang berkinerja baik: Ada juga Gobs yang akan menjadi penerus Protocol Buffer Google . Namun berbeda dengan semua format lain yang disebutkan, yang bukan bahasa-agnostik dan mengandalkan refleksi bawaan Go, ada juga pustaka Gobs untuk setidaknya bahasa lain selain Go.
Jawaban:
// Harap dicatat bahwa saya adalah penulis MessagePack. Jawaban ini mungkin bias.
Desain format
Kompatibilitas dengan JSON
Terlepas dari namanya, kompatibilitas BSON dengan JSON tidak begitu baik dibandingkan dengan MessagePack.
BSON memiliki tipe khusus seperti "ObjectId", "Min key", "UUID" atau "MD5" (menurut saya tipe ini dibutuhkan oleh MongoDB). Jenis ini tidak kompatibel dengan JSON. Itu berarti beberapa jenis informasi dapat hilang saat Anda mengonversi objek dari BSON ke JSON, tetapi tentu saja hanya jika jenis khusus ini ada di sumber BSON. Ini bisa menjadi kerugian untuk menggunakan JSON dan BSON dalam satu layanan.
MessagePack dirancang untuk dikonversi secara transparan dari / ke JSON.
MessagePack lebih kecil dari BSON
Format MessagePack kurang bertele-tele dari BSON. Hasilnya, MessagePack dapat membuat serial objek yang lebih kecil dari BSON.
Misalnya, peta sederhana {"a": 1, "b": 2} diserialkan dalam 7 byte dengan MessagePack, sedangkan BSON menggunakan 19 byte.
BSON mendukung pembaruan di tempat
Dengan BSON, Anda dapat memodifikasi bagian dari objek yang disimpan tanpa menserialisasi ulang seluruh objek. Misalkan peta {"a": 1, "b": 2} disimpan dalam sebuah file dan Anda ingin memperbarui nilai "a" dari 1 menjadi 2000.
Dengan MessagePack, 1 hanya menggunakan 1 byte tetapi 2000 menggunakan 3 byte. Jadi "b" harus dipindahkan mundur sebanyak 2 byte, sedangkan "b" tidak diubah.
Dengan BSON, 1 dan 2000 menggunakan 5 byte. Karena verbositas ini, Anda tidak perlu memindahkan "b".
MessagePack memiliki RPC
MessagePack, Protocol Buffer, Thrift dan Avro mendukung RPC. Tapi BSON tidak.
Perbedaan ini menyiratkan bahwa MessagePack pada awalnya dirancang untuk komunikasi jaringan sedangkan BSON dirancang untuk penyimpanan.
Implementasi dan desain API
MessagePack memiliki API pemeriksaan tipe (Java, C ++ dan D)
MessagePack mendukung pengetikan statis.
Pengetikan dinamis yang digunakan dengan JSON atau BSON berguna untuk bahasa dinamis seperti Ruby, Python, atau JavaScript. Tapi merepotkan untuk bahasa statis. Anda harus menulis kode pengecekan tipe yang membosankan.
MessagePack menyediakan API pemeriksaan tipe. Ini mengubah objek yang diketik secara dinamis menjadi objek yang diketik secara statis. Berikut adalah contoh sederhana (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 memiliki IDL
Ini terkait dengan API pemeriksaan tipe, MessagePack mendukung IDL. (spesifikasi tersedia dari: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )
Protocol Buffer dan Thrift memerlukan IDL (tidak mendukung pengetikan dinamis) dan menyediakan implementasi IDL yang lebih matang.
MessagePack memiliki API streaming (Ruby, Python, Java, C ++, ...)
MessagePack mendukung streaming deserializers. Fitur ini berguna untuk komunikasi jaringan. Berikut adalah contohnya (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 }
sumber
Saya tahu bahwa pertanyaan ini agak ketinggalan zaman pada saat ini ... Saya pikir sangat penting untuk menyebutkan bahwa itu tergantung pada seperti apa lingkungan klien / server Anda.
Jika Anda meneruskan byte beberapa kali tanpa pemeriksaan, seperti dengan sistem antrian pesan atau entri log streaming ke disk, Anda mungkin lebih memilih pengkodean biner untuk menekankan ukuran kompak. Jika tidak, itu adalah masalah kasus per kasus dengan lingkungan yang berbeda.
Beberapa lingkungan dapat memiliki serialisasi dan deserialisasi yang sangat cepat ke / dari msgpack / protobuf, yang lain tidak begitu banyak. Secara umum, semakin rendah level bahasa / lingkungan, serialisasi biner yang lebih baik akan berfungsi. Dalam bahasa tingkat yang lebih tinggi (node.js, .Net, JVM) Anda akan sering melihat bahwa serialisasi JSON sebenarnya lebih cepat. Pertanyaannya kemudian menjadi apakah overhead jaringan Anda lebih atau kurang dibatasi daripada memori / cpu Anda?
Berkenaan dengan msgpack vs bson vs buffer protokol ... msgpack adalah byte terkecil dari grup, buffer protokol hampir sama. BSON mendefinisikan tipe asli yang lebih luas daripada dua lainnya, dan mungkin lebih cocok untuk mode objek Anda, tetapi ini membuatnya lebih bertele-tele. Buffer protokol memiliki keuntungan karena dirancang untuk streaming ... yang membuatnya menjadi format yang lebih alami untuk format transfer / penyimpanan biner.
Secara pribadi, saya akan bersandar pada transparansi yang ditawarkan JSON secara langsung, kecuali jika ada kebutuhan yang jelas untuk lalu lintas yang lebih ringan. Melalui HTTP dengan data yang di-gzip, perbedaan dalam overhead jaringan bahkan lebih sedikit menjadi masalah antar format.
sumber
Pengujian cepat menunjukkan JSON yang diperkecil dideserialisasi lebih cepat daripada biner MessagePack. Dalam pengujian, Article.json adalah 550kb JSON yang diperkecil, Article.mpack adalah versi 420kb MP-nya. Mungkin masalah implementasi tentu saja.
MessagePack:
JSON:
Jadi waktunya adalah:
Jadi ruang disimpan, tetapi lebih cepat? Tidak.
Versi yang diuji:
sumber
simplejson
2.6.2 membutuhkan waktu 66,7 detik danmsgpack
0,2.2 hanya membutuhkan 28,8.Perbedaan utama yang belum disebutkan adalah bahwa BSON berisi informasi ukuran dalam byte untuk seluruh dokumen dan sub-dokumen bersarang lebih lanjut.
Ini memiliki dua manfaat utama untuk lingkungan terbatas (misalnya tertanam) di mana ukuran dan kinerja penting.
sumber
Saya membuat benchmark cepat untuk membandingkan kecepatan encoding dan decoding MessagePack vs BSON. BSON lebih cepat setidaknya jika Anda memiliki array biner yang besar:
Menggunakan C # Newtonsoft.Json dan MessagePack oleh neuecc:
sumber
Nah, seperti yang dikatakan penulis, MessagePack pada awalnya dirancang untuk komunikasi jaringan sedangkan BSON dirancang untuk penyimpanan.
MessagePack kompak sementara BSON verbose. MessagePack dimaksudkan untuk menjadi hemat ruang sementara BSON dirancang untuk CURD (hemat waktu).
Yang terpenting, sistem tipe MessagePack (awalan) mengikuti pengkodean Huffman, di sini saya menggambar pohon Huffman dari MessagePack (klik tautan untuk melihat gambar) :
sumber