paint-brush
रूबी वर्ल्ड में प्रोटोबफ बनाम जेएसओएनद्वारा@alexstaro
861 रीडिंग
861 रीडिंग

रूबी वर्ल्ड में प्रोटोबफ बनाम जेएसओएन

द्वारा Oleksandr Starodubtsev10m2023/04/26
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

प्रोटोबॉफ़ एक तेज़, कॉम्पैक्ट क्रॉस-प्लेटफ़ॉर्म संदेश प्रणाली है। इसमें एक परिभाषा भाषा और भाषा-विशिष्ट संकलक होते हैं। इसकी पिछली और आगे की संगतता बहुत तेज है (हम अभी तक निश्चित नहीं हैं), और उदाहरण के लिए JSON की तुलना में अधिक कॉम्पैक्ट है। यह संकुचित नहीं है और कुछ विशिष्ट प्रारूप उनके डेटा के लिए बेहतर काम कर सकते हैं।
featured image - रूबी वर्ल्ड में प्रोटोबफ बनाम जेएसओएन
Oleksandr Starodubtsev HackerNoon profile picture
0-item
1-item

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

प्रोटोबफ क्या है?

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

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


यह संकुचित नहीं है और कुछ विशिष्ट प्रारूप उनके डेटा के लिए बेहतर काम कर सकते हैं (उदाहरण के लिए जेपीईजी)। यह आत्म-वर्णन नहीं कर रहा है।


अधिक विवरण के लिए आधिकारिक डॉक्स देखें।

जेएसओएन क्या है

JSON जावास्क्रिप्ट ऑब्जेक्ट नोटेशन का संक्षिप्त नाम है। एक पाठ-आधारित डेटा प्रारूप, जो मूल रूप से जावास्क्रिप्ट में उपयोग किया गया था, लेकिन बाद में न केवल जेएस ऐप्स और बैकएंड के बीच बल्कि माइक्रोसर्विसेज के बीच भी एक संचार प्रारूप के रूप में व्यापक रूप से फैल गया और इसके कई अन्य उपयोग हैं।


यह स्ट्रिंग्स को चाबियों के रूप में उपयोग करता है और मूल्य के लिए उपलब्ध प्रकारों के रूप में एक स्ट्रिंग, संख्या, बूलियन, ऑब्जेक्ट, सरणी और नल है। इसका मुख्य लाभ यह है कि यह मानव-पठनीय है, और प्रोग्रामिंग भाषा के लिए क्रमबद्ध और पार्स करना बहुत आसान है।


अधिक विवरण के लिए साइट देखें।

मानक

मैंने तीन लोकप्रिय रूबी JSON लाइब्रेरी उठाईं। वे Oj, Yajl और मानक JSON लाइब्रेरी हैं। प्रोटोबफ के लिए, मैं Google रूबी मणि के साथ मानक Google प्रोटोक का उपयोग करता हूं।


मैं यह देखने के लिए विभिन्न विशिष्ट प्रकार के पेलोड को मापूंगा कि हम किस डेटा प्रकार को सबसे अधिक अंतर दिखाएंगे, जब तक कि फ़ील्ड प्रकारों के मिश्रण के साथ जटिल पेलोड।


आप यहां सभी कोड https://github.com/alexstaro/proto-vs-json देख सकते हैं।

बेंचमार्क सेटअप

एक हार्डवेयर के रूप में मैं AMD Ryzen 3 PRO 5450U और 16GB ddr4 ram के साथ लैपटॉप का उपयोग करता हूं।

एक ऑपरेटिंग सिस्टम के रूप में, मैं Ubuntu 22.10 काइनेटिक का उपयोग करता हूँ।


रूबी संस्करण 3.2.1 asdf के माध्यम से स्थापित किया गया था।


बेंचमार्किंग के लिए, मैं बेंचमार्क/ips मणि का उपयोग करता हूं ( https://github.com/evanphx/benchmark-ips )


सेटअप इस तरह दिखता है:

 Benchmark.ips do |x| x.config(time: 20, warmup: 5) x.report('Yajl encoding') do Yajl::Encoder.encode(data) end ... x.compare! end

केवल पूर्णांक

हम केवल पूर्णांकों से प्रारंभ करेंगे। JSON के लिए संख्याएँ बहुत कठिन हैं इसलिए हम उम्मीद करते हैं कि प्रोटोबॉफ़ अन्य प्रतिस्पर्धियों से बहुत दूर होगा।


टेस्ट डेटा:

 data = { field1: 2312345434234, field2: 31415926, field3: 43161592, field4: 23141596, field5: 61415923, field6: 323423434343443, field7: 53141926, field8: 13145926, field9: 323423434343443, field10: 43161592 }

बेंचमार्क परिणाम:

 protobuf encoding: 4146929.7 i/s Oj encoding: 1885092.0 i/s - 2.20x slower standard JSON encoding: 505697.5 i/s - 8.20x slower Yajl encoding: 496121.7 i/s - 8.36x slower


इसमें कोई संदेह नहीं है कि प्रोटोबॉफ़ एक पूर्ण विजेता है, लेकिन क्या होगा यदि हम परीक्षण को वास्तविक दुनिया के परिदृश्य के अधिक करीब बनाते हैं - हम लगभग हमेशा क्रमांकन के लिए प्रोटो संदेश बनाते हैं।


यदि हम बेंचमार्क के तहत मॉडल इनिशियलाइज़ेशन को स्थानांतरित करते हैं तो क्या होगा?


यहाँ परिणाम हैं:

 protobuf encoding: 4146929.7 i/s Oj encoding: 1885092.0 i/s - 2.20x slower standard JSON encoding: 505697.5 i/s - 8.20x slower Yajl encoding: 496121.7 i/s - 8.36x slower protobuf with model init: 489658.0 i/s - 8.47x slower


नतीजा इतना स्पष्ट नहीं है। मुझे उम्मीद थी कि संदेश इनिशियलाइज़ेशन के साथ एन्कोडिंग धीमी होगी लेकिन सबसे धीमी नहीं।


आइए अक्रमांकन की जाँच करें:

 protobuf parsing: 737979.5 i/s Oj parsing: 448833.9 i/s - 1.64x slower standard JSON parsing: 297127.2 i/s - 2.48x slower Yajl parsing: 184361.1 i/s - 4.00x slower

यहाँ कोई आश्चर्य नहीं हैं।


पेलोड आकार के संदर्भ में, प्रोटोबॉफ़, जोंस की तुलना में लगभग 4 गुना अधिक कॉम्पैक्ट है:

 JSON payload bytesize 201 Protobuf payload bytesize 58

केवल डबल्स

JSON के लिए डबल्स सबसे कठिन पेलोड होने की उम्मीद है, आइए इसे देखें।


हमारा पेलोड:


 data = { field1: 2312.345434234, field2: 31415.926, field3: 4316.1592, field4: 23141.596, field5: 614159.23, field6: 3234234.34343443, field7: 53141.926, field8: 13145.926, field9: 323423.434343443, field10: 43161.592 }


परिणाम:

 protobuf encoding: 4814662.9 i/s protobuf with model init: 444424.1 i/s - 10.83x slower Oj encoding: 297152.0 i/s - 16.20x slower Yajl encoding: 160251.9 i/s - 30.04x slower standard JSON encoding: 158724.3 i/s - 30.33x slower


मॉडल इनिशियलाइज़ेशन के साथ भी प्रोटोबॉफ़ बहुत तेज़ है। आइए अक्रमांकन की जाँच करें:

 Comparison: protobuf parsing: 822226.6 i/s Oj parsing: 395411.3 i/s - 2.08x slower standard JSON parsing: 241438.7 i/s - 3.41x slower Yajl parsing: 157235.7 i/s - 5.23x slower

यहां अभी भी कोई आश्चर्य नहीं है।


और पेलोड का आकार:

 JSON payload bytesize 211 Protobuf payload bytesize 90


चार बार नहीं, लेकिन फिर भी ध्यान देने योग्य।

केवल तार

JSON के लिए स्ट्रिंग्स के आसान होने की उम्मीद है, आइए इसे देखें।

पेलोड:


 data = { field1: "2312.345434234", field2: "31415.926", field3: "4316.1592", field4: "23141.596", field5: "614159.23", field6: "3234234.34343443", field7: "53141.926", field8: "13145.926", field9: "323423.434343443", field10: "43161.592" }


बेंच के परिणाम:

 Comparison: protobuf encoding: 3990298.3 i/s oj encoder: 1848941.3 i/s - 2.16x slower yajl encoder: 455222.0 i/s - 8.77x slower standard JSON encoding: 444245.6 i/s - 8.98x slower protobuf with model init: 368818.3 i/s - 10.82x slower


अक्रमांकन:

 Comparison: protobuf parser: 631262.5 i/s oj parser: 378697.6 i/s - 1.67x slower standard JSON parser: 322923.5 i/s - 1.95x slower yajl parser: 187593.4 i/s - 3.37x slower


पेलोड का आकार:

 JSON payload bytesize 231 Protobuf payload bytesize 129

पूर्णांक सरणी

भले ही हमने पूर्णांक बेंच को अलग कर दिया हो, यह दिलचस्प है कि प्रोटोबॉफ़ संग्रह को कैसे संभालता है।

यहाँ डेटा है:


 data = { field1: [ 2312345434234, 31415926, 43161592, 23141596, 61415923, 323423434343443, 53141926, 13145926, 323423434343443, 43161592 ] }


सीरियलाइज़ेशन बेंच:

 Comparison: protobuf encoding: 4639726.6 i/s oj encoder: 2929662.1 i/s - 1.58x slower standard JSON encoding: 699299.2 i/s - 6.63x slower yajl encoder: 610215.5 i/s - 7.60x slower protobuf with model init: 463057.9 i/s - 10.02x slower


अक्रमांकन बेंच:

 Comparison: oj parser: 1190763.1 i/s protobuf parser: 760307.3 i/s - 1.57x slower standard JSON parser: 619360.4 i/s - 1.92x slower yajl parser: 414352.4 i/s - 2.87x slower


ईमानदार होने के लिए, यहाँ डीरिएलाइज़ेशन के परिणाम बहुत अप्रत्याशित हैं।

पेलोड आकार की जाँच करें:

 JSON payload bytesize 121 Protobuf payload bytesize 50

डबल्स का ऐरे

मैंने यह जांचने का फैसला किया कि क्या डबल्स की एक सरणी समान व्यवहार साझा करती है।

आंकड़े:

 data = { field1: [ 2312.345434234, 31415.926, 4316.1592, 23141.596, 614159.23, 3234234.34343443, 53141.926, 13145.926, 323423.434343443, 43161.592 ] }


क्रमांकन:

 Comparison: protobuf encoding: 7667558.9 i/s protobuf with model init: 572563.4 i/s - 13.39x slower Oj encoding: 323818.1 i/s - 23.68x slower Yajl encoding: 183763.3 i/s - 41.73x slower standard JSON encoding: 182332.3 i/s - 42.05x slower


अक्रमांकन:

 Comparison: Oj parsing: 953384.6 i/s protobuf parsing: 883899.0 i/s - 1.08x slower standard JSON parsing: 452799.0 i/s - 2.11x slower Yajl parsing: 356091.2 i/s - 2.68x slower

हमें यहां भी ऐसे ही नतीजे मिले हैं। ऐसा लगता है कि प्रोटोबॉफ़ में सरणियों के साथ कुछ समस्याएँ हैं।


पेलोड का आकार:

 JSON payload bytesize 131 Protobuf payload bytesize 82

जटिल पेलोड

एक "जटिल" पेलोड के रूप में मैंने कुछ उपयोगकर्ता डेटा को उन पोस्ट के लिए पोस्ट और टिप्पणियों के साथ मज़ाक उड़ाया ताकि इसे वास्तविक जीवन एप्लिकेशन की तरह बनाया जा सके।

 data = { user_id: 12345, username: 'johndoe', email: '[email protected]', date_joined: '2023-04-01T12:30:00Z', is_active: true, profile: { full_name: 'John Doe', age: 30, address: '123 Main St, Anytown, USA', phone_number: '+1-555-123-4567' }, posts: [ { post_id: 1, title: 'My first blog post', content: 'This is the content of my first blog post.', date_created: '2023-04-01T14:00:00Z', likes: 10, tags: ['blog', 'first_post', 'welcome'], comments: [ { comment_id: 101, author: 'Jane', content: 'Great first post!', date_created: '2023-04-01T15:00:00Z', likes: 3 }, ... ] }, ... ] }


परिणाम:

 Comparison: protobuf encoding: 1038246.0 i/s Oj encoding: 296018.6 i/s - 3.51x slower Yajl encoding: 125909.6 i/s - 8.25x slower protobuf with model init: 119673.2 i/s - 8.68x slower standard JSON encoding: 115773.4 i/s - 8.97x slower Comparison: protobuf parsing: 291605.9 i/s Oj parsing: 76994.7 i/s - 3.79x slower standard JSON parsing: 64823.6 i/s - 4.50x slower Yajl parsing: 34936.4 i/s - 8.35x slower


और पेलोड का आकार:

 JSON payload bytesize 1700 Protobuf payload bytesize 876


हम यहां पहले स्थान पर शुद्ध प्रोटोबॉफ़ एन्कोडिंग के साथ अपेक्षित व्यवहार देखते हैं, हालाँकि, यदि हम अपने "वास्तविक दुनिया" उदाहरण को देखते हैं तो हम देखते हैं कि यह मानक JSON एन्कोडिंग से तेज़ नहीं है।

निष्कर्ष

यदि आप केवल गति के लिए JSON से Protobuf पर स्विच कर रहे हैं, तो यह इसके लायक नहीं हो सकता है।

प्रोटोबफ का उपयोग करने का कारण डेटा एक्सचेंज के लिए भयानक क्रॉस-लैंग्वेज स्कीमा परिभाषा होना चाहिए - प्रदर्शन को बढ़ावा नहीं।


इस लेख की मुख्य छवि हैकरनून केएआई इमेज जेनरेटर द्वारा प्रांप्ट "प्रोग्रामिंग लैंग्वेज" के माध्यम से तैयार की गई थी।