परफॉर्मेंट एंटिटी सीरियलाइजेशन: BSON बनाम मैसेजपैक (बनाम JSON)


137

हाल ही में मुझे MessagePack मिला है , जो Google के प्रोटोकॉल बफ़र्स और JSON के लिए एक वैकल्पिक द्विआधारी क्रमांकन प्रारूप है जो दोनों को बेहतर बनाता है।

इसके अलावा BSON क्रमांकन प्रारूप है जो MongoDB द्वारा डेटा संग्रहीत करने के लिए उपयोग किया जाता है।

क्या कोई व्यक्ति मतभेदों और बीएसएन बनाम मैसेजपैक के फायदे के बारे में बता सकता है ?


बस प्रदर्शन करने वाले द्विआधारी क्रमांकन प्रारूपों की सूची को पूरा करने के लिए: ऐसे गॉब्स भी हैं जो Google के प्रोटोकॉल बफ़र्स के उत्तराधिकारी बनने जा रहे हैं । हालाँकि , अन्य सभी उल्लिखित स्वरूपों के विपरीत, जो भाषा-अज्ञेय नहीं हैं और गो के अंतर्निहित प्रतिबिंब पर भरोसा करते हैं, गो के मुकाबले कम से कम अन्य भाषा के लिए गोब्स लाइब्रेरी भी हैं।


3
ज्यादातर विपणन प्रचार के भार की तरह लगता है। एक ["संकलित"] क्रमांकन प्रारूप का प्रदर्शन उपयोग किए गए कार्यान्वयन के कारण है। जबकि कुछ प्रारूपों में स्वाभाविक रूप से अधिक ओवरहेड होता है (जैसे कि JSON के रूप में यह सभी गतिशील रूप से संसाधित होता है), प्रारूप स्वयं "एक गति नहीं है"। पृष्ठ तब "पिक एंड चूज़" पर जाता है कि यह कैसे अपनी तुलना करता है ... यह एक गैर-निष्पक्ष फैशन है। मैरे बसकी बात नही हैं।

6
सुधार: Gobs का उद्देश्य प्रोटोकॉल बफ़र्स को प्रतिस्थापित करना नहीं है, और शायद कभी नहीं होगा। इसके अलावा, जीओबी भाषा अज्ञेय हैं (वे किसी भी भाषा में पढ़े / लिखे जा सकते हैं, कोड देख सकते हैं। Googlep/libgob ), लेकिन उन्हें बारीकी से परिभाषित किया जाता है कि गो डेटा से कैसे निपटता है, इसलिए वे गो के साथ सबसे अच्छा काम करते हैं।
काइल सी

6
Msgpack प्रदर्शन बेंचमार्क से लिंक टूट गया है ( msgpack.org/index/speedtest.png )।
अलीकसी रामानु ०

जवाबों:


197

// कृपया ध्यान दें कि मैं MessagePack का लेखक हूं। यह उत्तर पक्षपाती हो सकता है।

प्रारूप डिजाइन

  1. JSON के साथ संगतता

    इसके नाम के बावजूद, संदेश के साथ तुलना में JSON के साथ BSON की संगतता इतनी अच्छी नहीं है।

    BSON में विशेष प्रकार हैं जैसे "ObjectId", "Min key", "UUID" या "MD5" (मुझे लगता है कि ये प्रकार MongoDB द्वारा आवश्यक हैं)। ये प्रकार JSON के साथ संगत नहीं हैं। इसका मतलब है कि जब आप BSON से JSON में वस्तुओं को परिवर्तित करते हैं तो कुछ प्रकार की जानकारी खो सकते हैं, लेकिन निश्चित रूप से केवल जब ये विशेष प्रकार BSON स्रोत में होते हैं। यह एकल सेवा में JSON और BSON दोनों का उपयोग करने के लिए एक नुकसान हो सकता है।

    MessagePack को पारदर्शी रूप से / JSON से परिवर्तित करने के लिए डिज़ाइन किया गया है।

  2. मैसेजपैक BSON से छोटा है

    मैसेजपैक का प्रारूप BSON से कम क्रिया है। परिणामस्वरूप, MessagePack BSON से छोटी वस्तुओं को अनुक्रमित कर सकता है।

    उदाहरण के लिए, एक साधारण मानचित्र {"a": 1, "b": 2} 7 बाइट्स में MessagePack के साथ क्रमबद्ध है, जबकि BSON 19 बाइट्स का उपयोग करता है।

  3. BSON इन-प्लेस अपडेटिंग का समर्थन करता है

    BSON के साथ, आप संग्रहीत ऑब्जेक्ट के भाग को फिर से पूरे ऑब्जेक्ट को पुन: क्रमांकित किए बिना संशोधित कर सकते हैं। मान लीजिए कि कोई मानचित्र {"a": 1, "b": 2} एक फ़ाइल में संग्रहीत है और आप 1 से 2000 तक "a" का मान अद्यतन करना चाहते हैं।

    MessagePack के साथ, 1 केवल 1 बाइट का उपयोग करता है लेकिन 2000 3 बाइट्स का उपयोग करता है। तो "बी" को 2 बाइट्स से पीछे की ओर ले जाना चाहिए, जबकि "बी" को संशोधित नहीं किया गया है।

    BSON के साथ, 1 और 2000 दोनों 5 बाइट्स का उपयोग करते हैं। इस क्रिया के कारण, आपको "b" को स्थानांतरित करने की आवश्यकता नहीं है।

  4. MessagePack में RPC है

    MessagePack, प्रोटोकॉल बफ़र्स, थ्रिफ़्ट और एवरो RPC का समर्थन करते हैं। लेकिन BSON नहीं करता है।

इन अंतरों का मतलब है कि मैसेजपैक मूल रूप से नेटवर्क संचार के लिए डिज़ाइन किया गया है, जबकि बीएसओएन को स्टोरेज के लिए डिज़ाइन किया गया है।

कार्यान्वयन और एपीआई डिजाइन

  1. MessagePack में एपीआई (जावा, C ++ और D) टाइप-चेकिंग होती है।

    MessagePack स्थैतिक-टाइपिंग का समर्थन करता है।

    JSON या BSON के साथ उपयोग किया जाने वाला डायनामिक-टाइपिंग रूबी, पायथन या जावास्क्रिप्ट जैसी गतिशील भाषाओं के लिए उपयोगी है। लेकिन स्थिर भाषाओं के लिए परेशानी। आपको बोरिंग टाइप-चेकिंग कोड लिखना होगा।

    मैसेजपैक टाइप-चेकिंग एपीआई प्रदान करता है। यह गतिशील रूप से टाइप की गई वस्तुओं को सांख्यिकीय रूप से टाइप की गई वस्तुओं में परिवर्तित करता है। यहाँ एक सरल उदाहरण है (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 है

    यह प्रकार-जाँच API से संबंधित है, MessagePack IDL का समर्थन करता है। (विनिर्देश यहां से उपलब्ध है: http://wiki.msgpack.org/display/MSGPACK/Design+of+IDL )

    प्रोटोकॉल बफ़र्स और थ्रिफ़्ट के लिए IDL (डायनेमिक-टाइपिंग का समर्थन नहीं) की आवश्यकता होती है और अधिक परिपक्व IDL कार्यान्वयन प्रदान करते हैं।

  2. MessagePack में स्ट्रीमिंग API (रूबी, पायथन, जावा, C ++, ...) है

    MessagePack स्ट्रीमिंग deserializers का समर्थन करता है। यह सुविधा नेटवर्क संचार के लिए उपयोगी है। यहाँ एक उदाहरण है (रूबी):

    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
    }

33
मैसेजपैक डेटा प्रोटेक्शन के मामले में Google प्रोटोबॉफ़्स के साथ तुलना करता है, और परिणामस्वरूप, हवा के प्रदर्शन पर?
एलिस

4
पहला बिंदु इस तथ्य पर निर्भर करता है कि MessagePack में कच्ची बाइट्स क्षमता है जिसे JSON में प्रस्तुत नहीं किया जा सकता है। तो उस संबंध में BSON जैसा ही ...

4
@lttlrck आम तौर पर, कच्चे बाइट्स को एक स्ट्रिंग (आमतौर पर utf-8) माना जाता है, जब तक कि अन्यथा अपेक्षित न हो और चैनल के दोनों किनारों पर सहमत हो। msgpack का उपयोग स्ट्रीम / क्रमांकन प्रारूप ... और उस क्रिया को कम करने के रूप में किया जाता है .. हालाँकि मानव पठनीय भी कम है।
ट्रैकर 1

4
"मैसेजपैक में एपीआई की टाइपिंग की जाँच होती है। बीएसओएन नहीं है।" पूरी तरह से सही नहीं है। यह वास्तव में BSON कार्यान्वयन के लिए सांख्यिकीय रूप से टाइप की गई भाषाओं में भी सच है।
ब्रैंडन ब्लैक

1
MessagePack में अब BINARY डेटा टाइप है, इसलिए JSON के 1-1 डी-सीरियलाइजेशन संगतता का तर्क अब पूरी तरह से सच नहीं है।
zimbatm

16

मुझे पता है कि यह प्रश्न इस बिंदु पर थोड़ा दिनांकित है ... मुझे लगता है कि यह उल्लेख करना बहुत महत्वपूर्ण है कि यह इस बात पर निर्भर करता है कि आपका ग्राहक / सर्वर कैसा दिखता है।

यदि आप निरीक्षण के बिना कई बार बाइट्स पास कर रहे हैं, जैसे कि संदेश कतार प्रणाली या डिस्क में लॉग एंट्री स्ट्रीमिंग के साथ, तो आप कॉम्पैक्ट आकार पर जोर देने के लिए बाइनरी एन्कोडिंग को अच्छी तरह से पसंद कर सकते हैं। अन्यथा यह विभिन्न वातावरणों के साथ केस इश्यू का मामला है।

कुछ वातावरण बहुत तेजी से क्रमांकन और Mspack / protobuf के / से / के लिए deserialization हो सकता है, दूसरों को इतना नहीं। सामान्य तौर पर, भाषा / वातावरण जितना अधिक बेहतर होगा, बाइनरी क्रमांकन उतना ही बेहतर होगा। उच्च स्तर की भाषाओं में (नोड.जेएस, .नेट, जेवीएम) आप अक्सर देखेंगे कि JSON क्रमांकन वास्तव में तेज़ है। फिर सवाल यह है कि क्या आपका नेटवर्क आपकी मेमोरी / सीपीयू की तुलना में कम या ज्यादा बाधित है?

Mspack बनाम bson बनाम प्रोटोकॉल बफ़र्स के संबंध में ... msgpack समूह की सबसे कम बाइट्स है, प्रोटोकॉल बफ़र्स उसी के बारे में हैं। BSON अन्य दो की तुलना में अधिक व्यापक देशी प्रकारों को परिभाषित करता है, और आपके ऑब्जेक्ट मोड के लिए एक बेहतर मेल हो सकता है, लेकिन यह इसे और अधिक क्रिया बनाता है। प्रोटोकॉल बफ़र्स को स्ट्रीम के लिए डिज़ाइन किए जाने का लाभ है ... जो इसे द्विआधारी हस्तांतरण / भंडारण प्रारूप के लिए एक अधिक प्राकृतिक प्रारूप बनाता है।

निजी तौर पर, मैं उस पारदर्शिता की ओर झुकूंगा जो सीधे JSON प्रदान करती है, जब तक कि हल्के यातायात की स्पष्ट आवश्यकता नहीं है। Gzipped डेटा के साथ HTTP पर, नेटवर्क ओवरहेड में अंतर स्वरूपों के बीच एक समस्या से भी कम है।


6
मूल MsgPack केवल प्रोटोकॉलबफर्स ​​आकार-वार के साथ कुशल है, जिसकी लंबाई कुंजियों की लंबाई है (जो हमेशा-वर्तमान पाठ हैं) "a" या "b" जैसे संक्षिप्त हैं - या अन्यथा पूरे पेलोड का एक तुच्छ हिस्सा है । वे हमेशा प्रोटोकॉलबफर्स ​​में कम होते हैं जो आईडी फ़ील्ड / आईडी संकलन का उपयोग आईडी में करते हैं। यह वही है जो MsgPack को "गतिशील" बनाता है, जो कि प्रोटोकॉलबफर्स ​​सबसे निश्चित रूप से नहीं है ..
user2864740

2
अंत बिंदु अच्छा है, हालांकि: गज़िप / डिफ्लेट वास्तव में अच्छे हैं, ऐसे मामलों में कुंजियों की अतिरेक को संभाल रहे हैं जहां ऐसी चाबियाँ "लंबे समय तक लेकिन बार-बार अलॉट होती हैं" (MsgPack, JSON / BSON, और XML, आदि कई रिकॉर्ड्स में हैं, लेकिन इससे कोई मदद नहीं मिलेगी) यहां सभी पर प्रोटोकॉलबफर्स ​​.. एवरो स्कीमा को अलग से मैन्युअल रूप से प्रसारित करके मुख्य अतिरेक उन्मूलन करता है।
user2864740

4

त्वरित परीक्षण से पता चलता है कि मिनिमल JSON द्विआधारी MessagePack की तुलना में तेजी से डिसररलाइज्ड है। परीक्षणों में Article.json 550kb की न्यूनतम JSON है, Article.mpack इसका 420kb एमपी-संस्करण है। पाठ्यक्रम का कार्यान्वयन मुद्दा हो सकता है।

MessagePack:

//test_mp.js
var msg = require('msgpack');
var fs = require('fs');

var article = fs.readFileSync('Article.mpack');

for (var i = 0; i < 10000; i++) {
    msg.unpack(article);    
}

JSON:

// test_json.js
var msg = require('msgpack');
var fs = require('fs');

var article = fs.readFileSync('Article.json', 'utf-8');

for (var i = 0; i < 10000; i++) {
    JSON.parse(article);
}

तो समय हैं:

Anarki:Downloads oleksii$ time node test_mp.js 

real    2m45.042s
user    2m44.662s
sys     0m2.034s

Anarki:Downloads oleksii$ time node test_json.js 

real    2m15.497s
user    2m15.458s
sys     0m0.824s

तो अंतरिक्ष बचा है, लेकिन तेजी से? नहीं।

परीक्षण किए गए संस्करण:

Anarki:Downloads oleksii$ node --version
v0.8.12
Anarki:Downloads oleksii$ npm list msgpack
/Users/oleksii
└── msgpack@0.1.7  

7
निश्चित रूप से कार्यान्वयन पर निर्भर करता है। पायथन 2.7.3 के साथ मेरे परीक्षणों ने 489K test.json (409K समतुल्य test.msgpack) को खोलना दिखाया है कि 10,000 पुनरावृत्तियों के लिए simplejson2.6.2 को 66.7 सेकंड और msgpack0.2.2 को सिर्फ 28.8 लगते हैं।
दिन

2
यह Article.json कहां से आया?
Ant6n

दोस्तों, टेस्ट कोड ऊपर मेरी टिप्पणी में है, आपको और क्या उम्मीद थी, Article.json हमारे प्रोजेक्ट से json-serialized ऑब्जेक्ट है। और अब तक वे परिणाम अप्रासंगिक हो सकते हैं
ओलेक्सी खिलकेविच

14
यह एक उचित प्रदर्शन तुलना नहीं है, क्योंकि JS ने JSON को C ++ में मूल रूप से लागू किया है, जबकि JS में Mspack।
एलेक्स पैनचोको

2
आप MessagePack को लैटिन रोमन की तुलना में बेहतर बनाने की कोशिश कर रहे हैं। JSON जावास्क्रिप्ट का मूल (C ++) है जबकि MessagePack जावास्क्रिप्ट में लिखा गया है, जिसकी व्याख्या की गई है। यह मूल रूप से दो कोड स्निपेट की तुलना कर रहा है, एक जावास्क्रिप्ट में लिखा गया है और दूसरा C ++ में लिखा गया है।
रमज़ान पोलाट

0

एक महत्वपूर्ण अंतर जो अभी तक उल्लिखित नहीं है, वह यह है कि BSON में संपूर्ण दस्तावेज़ों के लिए बाइट्स में आकार की जानकारी और आगे के नेस्टेड उप-दस्तावेज़ शामिल हैं।

document    ::=     int32 e_list

प्रतिबंधित वातावरण (जैसे एम्बेडेड) के लिए इसके दो प्रमुख लाभ हैं जहां आकार और प्रदर्शन महत्वपूर्ण है।

  1. आप तुरंत जांच सकते हैं कि क्या आप जिस डेटा को पार्स करने जा रहे हैं वह एक पूर्ण दस्तावेज़ का प्रतिनिधित्व करता है या यदि आपको किसी बिंदु पर अधिक अनुरोध करने की आवश्यकता है (कुछ कनेक्शन या भंडारण से हो)। चूंकि यह एक अतुल्यकालिक ऑपरेशन की संभावना है, इसलिए आप पहले ही पार्स करने से पहले एक नया अनुरोध भेज सकते हैं।
  2. आपके डेटा में आपके लिए अप्रासंगिक जानकारी के साथ पूरे उप-दस्तावेज हो सकते हैं। BSON आपको इसे छोड़ने के लिए उप-दस्तावेज़ के आकार की जानकारी का उपयोग करके उप-दस्तावेज़ के पिछले ऑब्जेक्ट पर आसानी से पार करने की अनुमति देता है। दूसरी ओर मेसपैक में व्हाट्स के अंदर तत्वों की संख्या होती है जिसे मैप कहा जाता है (बीएसओएन के उप-दस्तावेजों के समान)। हालांकि यह निस्संदेह उपयोगी जानकारी है, यह पार्सर की मदद नहीं करता है। आपको अभी भी नक्शे के अंदर हर एक वस्तु को पार्स करना होगा और इसे छोड़ नहीं सकते। आपके डेटा की संरचना के आधार पर इसका प्रदर्शन पर भारी प्रभाव पड़ सकता है।

0

मैंने मैसेजपैक बनाम बीएसओएन की एन्कोडिंग और डिकोडिंग गति की तुलना करने के लिए त्वरित बेंचमार्क बनाया। यदि आपके पास बड़ी बाइनरी सरणियाँ हैं तो BSON कम से कम तेज़ है:

BSON writer: 2296 ms (243487 bytes)
BSON reader: 435 ms
MESSAGEPACK writer: 5472 ms (243510 bytes)
MESSAGEPACK reader: 1364 ms

C # Newtonsoft.Json और MessagePack का उपयोग neuecc द्वारा:

    public class TestData
    {
        public byte[] buffer;
        public bool foobar;
        public int x, y, w, h;
    }

    static void Main(string[] args)
    {
        try
        {
            int loop = 10000;

            var buffer = new TestData();
            TestData data2;
            byte[] data = null;
            int val = 0, val2 = 0, val3 = 0;

            buffer.buffer = new byte[243432];

            var sw = new Stopwatch();

            sw.Start();
            for (int i = 0; i < loop; i++)
            {
                data = SerializeBson(buffer);
                val2 = data.Length;
            }

            var rc1 = sw.ElapsedMilliseconds;

            sw.Restart();
            for (int i = 0; i < loop; i++)
            {
                data2 = DeserializeBson(data);
                val += data2.buffer[0];
            }
            var rc2 = sw.ElapsedMilliseconds;

            sw.Restart();
            for (int i = 0; i < loop; i++)
            {
                data = SerializeMP(buffer);
                val3 = data.Length;
                val += data[0];
            }

            var rc3 = sw.ElapsedMilliseconds;

            sw.Restart();
            for (int i = 0; i < loop; i++)
            {
                data2 = DeserializeMP(data);
                val += data2.buffer[0];
            }
            var rc4 = sw.ElapsedMilliseconds;

            Console.WriteLine("Results:", val);
            Console.WriteLine("BSON writer: {0} ms ({1} bytes)", rc1, val2);
            Console.WriteLine("BSON reader: {0} ms", rc2);
            Console.WriteLine("MESSAGEPACK writer: {0} ms ({1} bytes)", rc3, val3);
            Console.WriteLine("MESSAGEPACK reader: {0} ms", rc4);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadLine();
    }

    static private byte[] SerializeBson(TestData data)
    {
        var ms = new MemoryStream();

        using (var writer = new Newtonsoft.Json.Bson.BsonWriter(ms))
        {
            var s = new Newtonsoft.Json.JsonSerializer();
            s.Serialize(writer, data);
            return ms.ToArray();
        }
    }

    static private TestData DeserializeBson(byte[] data)
    {
        var ms = new MemoryStream(data);

        using (var reader = new Newtonsoft.Json.Bson.BsonReader(ms))
        {
            var s = new Newtonsoft.Json.JsonSerializer();
            return s.Deserialize<TestData>(reader);
        }
    }

    static private byte[] SerializeMP(TestData data)
    {
        return MessagePackSerializer.Typeless.Serialize(data);
    }

    static private TestData DeserializeMP(byte[] data)
    {
        return (TestData)MessagePackSerializer.Typeless.Deserialize(data);
    }

0

खैर Well जैसा कि लेखक ने कहा P MessagePack मूल रूप से नेटवर्क संचार के लिए डिज़ाइन किया गया है जबकि BSON को स्टोरेज के लिए डिज़ाइन किया गया है।

MessagePack कॉम्पैक्ट है जबकि BSON क्रिया है। MessagePack का मतलब अंतरिक्ष-कुशल होना है जबकि BSON CURD (समय-कुशल) के लिए डिज़ाइन किया गया है।

सबसे महत्वपूर्ण बात, मैसेजपैक का टाइप सिस्टम (उपसर्ग) हफमैन एन्कोडिंग का अनुसरण करता है, यहां मैंने मैसेजपैक का हफमैन ट्री बनाया (छवि देखने के लिए लिंक पर क्लिक करें) ack

मैसेजपैक का हफमैन ट्री

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.