PHP सरणियों को स्टोर करने के लिए पसंदीदा तरीका (json_encode बनाम क्रमबद्ध)


609

मुझे कैशिंग प्रयोजनों के लिए एक फ्लैट फ़ाइल में डेटा के बहुआयामी साहचर्य सरणी को संग्रहीत करने की आवश्यकता है। मैं कभी-कभी अपने वेब ऐप में उपयोग के लिए इसे JSON में बदलने की आवश्यकता पर आ सकता हूं, लेकिन अधिकांश समय मैं PHP में सीधे सरणी का उपयोग करूंगा।

JSON के रूप में या इस पाठ फ़ाइल में PHP क्रमबद्ध सरणी के रूप में सरणी को संग्रहीत करना अधिक कुशल होगा? मैंने चारों ओर देखा है और ऐसा लगता है कि PHP (5.3) के नवीनतम संस्करणों में, json_decodeवास्तव में से तेज है unserialize

मैं वर्तमान में JSON के रूप में सरणी को संग्रहीत करने की दिशा में झुकाव कर रहा हूं क्योंकि मुझे लगता है कि यदि मानव द्वारा पढ़ना आसान है, तो इसे बहुत कम प्रयास के साथ PHP और जावास्क्रिप्ट दोनों में उपयोग किया जा सकता है, और जो मैंने पढ़ा है, वह भी हो सकता है डिकोड करने के लिए तेज़ (एन्कोडिंग के बारे में निश्चित नहीं है, हालांकि)।

क्या किसी को किसी भी नुकसान का पता है? किसी के पास किसी भी तरीके के प्रदर्शन लाभ दिखाने के लिए अच्छे मानक हैं?

जवाबों:


563

आपकी प्राथमिकताओं पर निर्भर करता है।

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

  • इसके विपरीत serialize()आपको UTF-8 वर्णों को अछूता रखने के लिए अतिरिक्त पैरामीटर जोड़ने की आवश्यकता है: json_encode($array, JSON_UNESCAPED_UNICODE) (अन्यथा यह UTF-8 वर्णों को यूनिकोड एस्केप अनुक्रमों में परिवर्तित करता है)।
  • JSON को इस बात की कोई याद नहीं होगी कि ऑब्जेक्ट की मूल कक्षा क्या थी (उन्हें हमेशा stdClass के उदाहरण के रूप में पुनर्स्थापित किया जाता है)।
  • आप लाभ नहीं उठा सकते __sleep()और __wakeup()JSON के साथ
  • डिफ़ॉल्ट रूप से, केवल सार्वजनिक संपत्तियों को JSON के साथ क्रमबद्ध किया जाता है। ( इस व्यवहार को बदलने के लिए PHP>=5.4आप JsonSerializable को लागू कर सकते हैं)।
  • JSON अधिक पोर्टेबल है

और शायद कुछ अन्य मतभेद हैं जो मैं इस समय नहीं सोच सकता।

दो की तुलना करने के लिए एक सरल गति परीक्षण

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);

// Time json encoding
$start = microtime(true);
json_encode($testArray);
$jsonTime = microtime(true) - $start;
echo "JSON encoded in $jsonTime seconds\n";

// Time serialization
$start = microtime(true);
serialize($testArray);
$serializeTime = microtime(true) - $start;
echo "PHP serialized in $serializeTime seconds\n";

// Compare them
if ($jsonTime < $serializeTime) {
    printf("json_encode() was roughly %01.2f%% faster than serialize()\n", ($serializeTime / $jsonTime - 1) * 100);
}
else if ($serializeTime < $jsonTime ) {
    printf("serialize() was roughly %01.2f%% faster than json_encode()\n", ($jsonTime / $serializeTime - 1) * 100);
} else {
    echo "Impossible!\n";
}

function fillArray( $depth, $max ) {
    static $seed;
    if (is_null($seed)) {
        $seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
    }
    if ($depth < $max) {
        $node = array();
        foreach ($seed as $key) {
            $node[$key] = fillArray($depth + 1, $max);
        }
        return $node;
    }
    return 'empty';
}

31
"JSON यूटीएफ -8 वर्णों को यूनिकोड एस्केप अनुक्रमों में परिवर्तित करता है।" अब जरूरी नहीं सच: अब हमारे पास है JSON_UNESCAPED_UNICODE
TRIG

32
यहां हम लगभग 5 साल बाद हैं और मैंने परीक्षण फिर से (सिर्फ json_encode) चलाया और यह अब क्रमबद्ध की तुलना में लगभग 131% तेज है। तो, 5.3.x पर 5.4.x में उस फ़ंक्शन में कुछ बहुत अच्छे सुधार होने चाहिए। विशेष रूप से, मैं CentOS 6 पर 5.4.24 चला रहा हूं। इसलिए, JSON के लिए हाँ !!
काइलफ़ारिस

8
मेरे मामले में हम, तो हम बनाम unserialize json_decode बेंचमार्क और परिणाम JSON में .06662392616272 सेकंड <br> पीएचपी dcoded में 0.093269109725952 सेकंड <br> json_decode unserialized था एक बार सांकेतिक शब्दों में बदलना और एक बहुत डिकोड () मोटे तौर पर 39.99% की तुलना में तेजी unserialize था ()
AMB

21
दिलचस्प: यदि आप इस कोड को 3v4l.org पर चलाते हैं , तो नवीनतम PHP7 विकास json_encode की तुलना में तेजी से क्रमबद्ध चलता है: "serialize () json_encode ()" की तुलना में लगभग 76.53% तेज है
marvvangend

21
2017, पीएचपी 7.1 औरserialize() was roughly 35.04% faster than json_encode()
एलियास सोरेस

239

JSON PHP के क्रमांकन प्रारूप की तुलना में सरल और तेज़ है और जब तक इसका उपयोग नहीं किया जाना चाहिए :

  • आप गहरी नेस्टेड सरणियों का भंडारण कर रहे हैं json_decode(): "यह फ़ंक्शन झूठा वापस आ जाएगा यदि JSON एन्कोडेड डेटा 127 तत्वों से अधिक गहरा हो।"
  • आप उन वस्तुओं को संग्रहीत कर रहे हैं, जिन्हें सही वर्ग के रूप में अनसुना करने की आवश्यकता है
  • आप पुराने PHP संस्करणों के साथ बातचीत कर रहे हैं जो json_decode का समर्थन नहीं करते हैं

12
बहुत बढ़िया जवाब। हाहा, 127 का स्तर गहरा एक पागल सा लगता है; शुक्र है कि मैं केवल 2-3 सबसे अधिक पसंद कर रहा हूं। क्या आपके पास इस तथ्य का बैकअप लेने के लिए कोई डेटा है कि json_decode / json_encode अनसेरीलाइज़ / सीरीज़ की तुलना में तेज़ है?
काइलफ़ारिस

1
मैंने कुछ समय पहले इसका परीक्षण किया था और json तेजी से बाहर आया था - मेरे पास हालांकि कोई डेटा नहीं है।
ग्रेग

47
"5.3.0 ने वैकल्पिक गहराई को जोड़ा। डिफ़ॉल्ट पुनरावृत्ति की गहराई को 128 से बढ़ाकर 512 कर दिया गया"
जियोर्जियो

4
मैं उपरोक्त सूची में एक और आइटम जोड़ूंगा: json_encode () का उपयोग नहीं किया जाना चाहिए यदि आपके डेटा में अमान्य UTF-8 बाइट अनुक्रम हो सकते हैं। यह केवल ऐसे डेटा के लिए गलत है। उदाहरण के लिए प्रयास करें: var_dump (json_encode ("\ xEF \ xEF"));
पको

1
यह सच नहीं है कि यह सामान्य रूप से तेज है। यदि आपके पास लगभग ~ 500 प्रविष्टियों के साथ एक छोटा सा सरणी है, तो अनसेरिज़ल / सीरीज़ वास्तव में 200-400% तेज है तो json_decode / json_encode (PHP 5.6.19)
एडम

59

मैंने इस विषय के बारे में एक ब्लॉगपोस्ट लिखा है: " कैश एक बड़ा सरणी: JSON, क्रमबद्ध या var_export? " । इस पोस्ट में यह दिखाया गया है कि छोटे से लेकर बड़े आकार के सरणियों के लिए क्रमबद्धता सबसे अच्छी पसंद है। बहुत बड़ी सरणियों (> 70MB) के लिए JSON बेहतर विकल्प है।


8
लिंक कोई और उपलब्ध नहीं है।
मार्टिन थॉमा

1
धन्यवाद, मूस, मैंने लिंक अपडेट किया है। हालांकि लेख लगभग 6 साल पुराना है और वर्तमान PHP संस्करणों के लिए इतना सटीक नहीं हो सकता है।
टैको

मैंने कुछ परीक्षण किए और लगभग 300 पुनरावृत्तियों के साथ, बड़े सरणियों (उन लोगों के लिए पीटर बेली का उपयोग किया गया कार्य) के साथ इसका परीक्षण करने के लिए एक सरल कार्य किया, json_encode()लगभग 80% से 150% तेजी से (इसके वास्तव में ऊपर और नीचे जा रहा है) serialize()। लेकिन छोटे सरणियों ( array("teams" => array(1 => array(4 arrays of players), 2 => array(4 arrays of players)))) का उपयोग करते समय , मैंने 750,000 पुनरावृत्तियों के साथ परीक्षण किया और उस मामले में serialize()लगभग 6% से 10% तेज है। मेरा कार्य सभी पुनरावृत्तियों के लिए औसत समय लेता है और उनकी तुलना करता है। मैं इसे यहाँ उत्तर में से एक के रूप में पोस्ट कर सकता हूँ
MiChAeLoKGB

अगर प्रोटोकॉल केवल PHP द्वारा उपयोग किया जाता है, तो var_export मेरी चीज है। बस शामिल विचार में संभावित वाक्यविन्यास त्रुटियों से सावधान रहने की जरूरत है।
Gfra54

3
ब्लॉग अब मौजूद नहीं है
popeye

53

आपको https://github.com/phadej/igbinary में भी रुचि हो सकती है - जो PHP के लिए एक अलग क्रमांकन 'इंजन' प्रदान करता है।

64 बिट प्लेटफॉर्म शो में PHP 5.3.5 का उपयोग करके मेरा यादृच्छिक / मनमाना 'प्रदर्शन' आंकड़े:

JSON:

  • JSON 2.180496931076 सेकंड में एन्कोड किया गया
  • JSON 9.8368630409241 सेकंड में डिकोड हो गया
  • क्रमबद्ध "स्ट्रिंग" आकार: 13993

मूल निवासी PHP:

  • PHP ने 2.9125759601593 सेकंड में सीरियल किया
  • PHP ने 6.4348418712616 सेकंड्स में अनसोर्स्ड किया
  • क्रमबद्ध "स्ट्रिंग" आकार: 20769

Igbinary:

  • 1.6099879741669 सेकंड में विजयी क्रमिक जीत
  • ४.ig20३28 ९ २०२ WIN४२ .१ सेकंड में जीत हासिल की
  • जीत क्रमबद्ध "स्ट्रिंग" आकार: 4467

तो, यह igbinary_serialize () और igbinary_unserialize () के लिए तेज़ है और अन्य डिस्क स्थान का उपयोग करता है।

मैंने ऊपर के रूप में fillArray (0, 3) कोड का उपयोग किया, लेकिन सरणी कुंजियों को अधिक लंबा बना दिया।

igbinary PHP के देशी क्रमबद्ध (ऑब्जेक्ट्स आदि के साथ कोई समस्या नहीं है) के समान डेटा स्टोर कर सकता है और यदि आप चाहें तो PHP5.3 को सत्र हैंडलिंग के लिए इसका उपयोग करने के लिए कह सकते हैं।

यह भी देखें http://ilia.ws/files/zendcon_2010_hidden_features.pdf - विशेष रूप से स्लाइड्स 14: 15-10-16


25

Y ने केवल क्रमबद्ध और जसन एन्कोड और डिकोड का परीक्षण किया है, साथ ही आकार यह संग्रहीत स्ट्रिंग को ले जाएगा।

JSON encoded in 0.067085981369 seconds. Size (1277772)
PHP serialized in 0.12110209465 seconds. Size (1955548)
JSON decode in 0.22470498085 seconds
PHP serialized in 0.211947917938 seconds
json_encode() was roughly 80.52% faster than serialize()
unserialize() was roughly 6.02% faster than json_decode()
JSON string was roughly 53.04% smaller than Serialized string

हम यह निष्कर्ष निकाल सकते हैं कि JSON तेजी से एन्कोड करता है और एक छोटी स्ट्रिंग का परिणाम देता है, लेकिन स्ट्रिंग को डीकोड करने के लिए unserialize तेज है।


6
मुझे नहीं पता कि लोग इतने छोटे डेटासेट के साथ प्रदर्शन परीक्षण क्यों करते हैं। ऐसा करना कि आपके पास सभी ओवरहेड हैं जो आपके परिणामों में त्रुटियां जोड़ते हैं। और अगर लोग प्रदर्शन में रुचि रखते हैं, तो यह संभवतः इसलिए है क्योंकि उनके पास एक बहुत बड़ा डेटासेट है, क्योंकि एक बार माइक्रो सेकंड हासिल करने का कोई मतलब नहीं है।
यन सागन

1
अक्सर मैं कई छोटे डेटासेट पर पुनरावृति करता हूं। सैकड़ों छोटे डेटासेट के साथ, प्रत्येक के लिए 1mS प्राप्त करना अभी भी दिलचस्प है।
टेसन

@YannSagon यहां तक ​​कि छोटे डेटासेट के साथ यह एक प्रदर्शन परीक्षण करने के लिए समझ में आता है। परीक्षण से पहले आपको यह कैसे पता होना चाहिए कि यह केवल एक माइक्रो सेकंड के बारे में है?
एडम

17

यदि आप ऐसी जानकारी को कैशिंग कर रहे हैं जिसे आप अंततः बाद के समय में "शामिल" करना चाहेंगे, तो आप var_export का उपयोग करके प्रयास करना चाह सकते हैं । इस तरह आप केवल "सीरियलाइज़" में हिट लेते हैं, न कि "अनसेरिज़ल" में।


यह संभवत: सबसे तेज़ तरीका है। मैंने SO पर एक उदाहरण लिखा "PHP - fast serialize /
unserialize

12

मैंने परीक्षण को अमान्य करने के लिए अयोग्यता प्रदर्शन शामिल किया। यहां मुझे नंबर मिले।

Serialize

JSON encoded in 2.5738489627838 seconds
PHP serialized in 5.2861361503601 seconds
Serialize: json_encode() was roughly 105.38% faster than serialize()


Unserialize

JSON decode in 10.915472984314 seconds
PHP unserialized in 7.6223039627075 seconds
Unserialize: unserialize() was roughly 43.20% faster than json_decode() 

तो जंक एन्कोडिंग के लिए तेज़ लगता है लेकिन डिकोडिंग में धीमा है। तो यह आपके आवेदन पर निर्भर करता है और आप सबसे अधिक क्या करने की उम्मीद करते हैं।


9

वास्तव में अच्छा विषय और कुछ जवाब पढ़ने के बाद, मैं इस विषय पर अपने प्रयोगों को साझा करना चाहता हूं।

मुझे एक उपयोग का मामला मिला जहां कुछ "विशाल" तालिका को लगभग हर बार डेटाबेस से बात करने की आवश्यकता होती है (यह मत पूछो कि क्यों, बस एक तथ्य)। डेटाबेस कैशिंग सिस्टम उचित नहीं है क्योंकि यह विभिन्न अनुरोधों को कैश नहीं करेगा, इसलिए मैं php कैशिंग सिस्टम के बारे में बताता हूं।

मैंने कोशिश की, apcuलेकिन यह जरूरतों के अनुकूल नहीं था, स्मृति इस मामले में पर्याप्त विश्वसनीय नहीं है। अगला कदम क्रमांकन के साथ एक फ़ाइल को कैश करना था।

तालिका में 18 स्तंभों के साथ 14355 प्रविष्टियाँ हैं, जो क्रमबद्ध कैशे को पढ़ने पर मेरे परीक्षण और आँकड़े हैं:

JSON:

जैसा कि आप सभी ने कहा है, json_encode/ के साथ प्रमुख असुविधा json_decodeयह है कि यह सब कुछ एक StdClassउदाहरण (या वस्तु) में बदल देता है। यदि आपको इसे लूप करने की आवश्यकता है, तो इसे एक सरणी में बदलना जो आप शायद करेंगे, और हां यह परिवर्तन समय बढ़ा रहा है

औसत समय: 780.2 एमएस; मेमोरी का उपयोग: 41.5MB; कैश फ़ाइल का आकार: 3.8MB

Msgpack

@ हच मेसकप का उल्लेख करता है । सुंदर वेबसाइट। चलो इसे एक कोशिश हम देंगे?

औसत समय: 497 एमएस; मेमोरी का उपयोग: 32 एमबी; कैश फ़ाइल का आकार: 2.8 एमबी

यह बेहतर है, लेकिन एक नए विस्तार की आवश्यकता है; कभी-कभी लोगों को डराने के लिए संकलन ...

IgBinary

@GingerDog उल्लेख igbinary । ध्यान दें कि मैंने सेट किया है igbinary.compact_strings=Offक्योंकि मुझे फ़ाइल आकार की तुलना में प्रदर्शन पढ़ने की अधिक परवाह है।

औसत समय: 411.4 एमएस; मेमोरी का उपयोग: 36.75MB; कैश फ़ाइल का आकार: 3.3MB

मेस पैक से बेहतर है। फिर भी, इस संकलन की भी आवश्यकता है।

serialize/unserialize

औसत समय: 477.2 एमएस; मेमोरी का उपयोग: 36.25MB; कैश फ़ाइल का आकार: 5.9 एमबी

JSON से बेहतर प्रदर्शन, बड़ा सरणी है, धीमी json_decodeहै, लेकिन आप पहले से ही नया है।

वे बाहरी एक्सटेंशन फ़ाइल आकार को कम कर रहे हैं और कागज पर बहुत अच्छा लगता है। नंबर झूठ नहीं बोलते *। यदि आप लगभग एक ही परिणाम प्राप्त करते हैं, तो एक एक्सटेंशन संकलित करने का क्या मतलब है जो आपके पास मानक PHP फ़ंक्शन के साथ होगा?

हम यह भी काट सकते हैं कि आपकी आवश्यकताओं के आधार पर, आप किसी और की तुलना में कुछ अलग चुनेंगे:

  • IgBinary वास्तव में अच्छा है और MsgPack की तुलना में बेहतर प्रदर्शन करता है
  • Msgpack आपके डेटा को संपीड़ित करने में बेहतर है (ध्यान दें कि मैंने igbinary कॉम्पैक्ट.string विकल्प की कोशिश नहीं की थी)।
  • संकलन नहीं करना चाहते हैं? मानकों का उपयोग करें।

यही कारण है, एक और क्रमांकन तरीकों की मदद से आप एक को चुनने में मदद करते हैं!

* PHPUnit 3.7.31, php 5.5.10 के साथ परीक्षण किया गया - केवल एक मानक हार्डड्राइव और पुराने दोहरे कोर सीपीयू के साथ डिकोडिंग - 10 समान उपयोग मामले के परीक्षण पर औसत संख्या, आपके आँकड़े भिन्न हो सकते हैं


वापस लौटने के लिए मजबूर करने के लिए ध्वज को json_d timecode में क्यों नहीं?
एलेक्स यरोशेविच

क्योंकि यह धीमा है। मैंने इसका परीक्षण नहीं किया, लेकिन मुझे लगता है कि बस php से टाइप परिवर्तन के लिए मजबूर करना तेज है।
सोयूका

मुझे बस इतना पता है कि php में ऑब्जेक्ट्स की तुलना में arrays को बहुत तेजी से बनाना है।
एलेक्स यरोशेविच

तो आप के बारे में बात कर रहे हैं json_decode($object, true), मूल रूप से यह वही है, (array) json_decode($object)लेकिन पुनरावृत्ति के रूप में एक ही व्यवहार होगा और यह दोनों मामलों में एक महत्वपूर्ण लागत होगा। ध्यान दें कि मैं के बीच प्रदर्शन डिफ परीक्षण नहीं किया StdClassऔर arrayलेकिन यह है कि के नहीं वास्तव में यहां मुद्दा यह है।
सोयाका

मुझे यकीन है कि यह एक और लागत है क्योंकि यह वस्तुओं के बिना निचले स्तर पर किया जाता है।
एलेक्स यरोशेविच

8

धारावाहिक की तरह लगता है कि मैं 2 कारणों के लिए उपयोग करने जा रहा हूँ:

  • किसी ने बताया कि json_decode की तुलना में unserialize तेज़ है और एक 'रीड' केस 'राइट' केस की तुलना में अधिक संभावित लगता है।

  • जब मुझे अमान्य UTF-8 वर्णों के साथ तार होने पर json_encode से परेशानी होती है। जब ऐसा होता है तो स्ट्रिंग समाप्त हो जाती है, जिससे जानकारी समाप्त हो जाती है।


क्या आप एक उदाहरण के साथ अपने अंतिम बिंदु को विस्तृत कर सकते हैं
नवीन सरोए

6

मैंने इसे काफी जटिल रूप से परीक्षण किया है, इसमें सभी प्रकार के डेटा (स्ट्रिंग, NULL, पूर्णांक) के साथ हल्के से नेस्टेड मल्टी-हैश है, और json_encode / json_decode की तुलना में इसे बहुत तेज़ी से समाप्त किया गया है।

मेरे परीक्षणों में एकमात्र फायदा जौन का था, वह छोटा 'पैक्ड' आकार का था।

ये PHP 5.3.3 के तहत किए गए हैं, मुझे बताएं कि क्या आप अधिक विवरण चाहते हैं।

यहाँ परीक्षण के परिणाम हैं तो कोड उन्हें उत्पादन करने के लिए। मैं परीक्षण डेटा प्रदान नहीं कर सकता क्योंकि यह जानकारी देगा कि मैं जंगल में बाहर जाने नहीं दे सकता।

JSON encoded in 2.23700618744 seconds
PHP serialized in 1.3434419632 seconds
JSON decoded in 4.0405561924 seconds
PHP unserialized in 1.39393305779 seconds

serialized size : 14549
json_encode size : 11520
serialize() was roughly 66.51% faster than json_encode()
unserialize() was roughly 189.87% faster than json_decode()
json_encode() string was roughly 26.29% smaller than serialize()

//  Time json encoding
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    json_encode( $test );
}
$jsonTime = microtime( true ) - $start;
echo "JSON encoded in $jsonTime seconds<br>";

//  Time serialization
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    serialize( $test );
}
$serializeTime = microtime( true ) - $start;
echo "PHP serialized in $serializeTime seconds<br>";

//  Time json decoding
$test2 = json_encode( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    json_decode( $test2 );
}
$jsonDecodeTime = microtime( true ) - $start;
echo "JSON decoded in $jsonDecodeTime seconds<br>";

//  Time deserialization
$test2 = serialize( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
    unserialize( $test2 );
}
$unserializeTime = microtime( true ) - $start;
echo "PHP unserialized in $unserializeTime seconds<br>";

$jsonSize = strlen(json_encode( $test ));
$phpSize = strlen(serialize( $test ));

echo "<p>serialized size : " . strlen(serialize( $test )) . "<br>";
echo "json_encode size : " . strlen(json_encode( $test )) . "<br></p>";

//  Compare them
if ( $jsonTime < $serializeTime )
{
    echo "json_encode() was roughly " . number_format( ($serializeTime / $jsonTime - 1 ) * 100, 2 ) . "% faster than serialize()";
}
else if ( $serializeTime < $jsonTime )
{
    echo "serialize() was roughly " . number_format( ($jsonTime / $serializeTime - 1 ) * 100, 2 ) . "% faster than json_encode()";
} else {
    echo 'Unpossible!';
}
    echo '<BR>';

//  Compare them
if ( $jsonDecodeTime < $unserializeTime )
{
    echo "json_decode() was roughly " . number_format( ($unserializeTime / $jsonDecodeTime - 1 ) * 100, 2 ) . "% faster than unserialize()";
}
else if ( $unserializeTime < $jsonDecodeTime )
{
    echo "unserialize() was roughly " . number_format( ($jsonDecodeTime / $unserializeTime - 1 ) * 100, 2 ) . "% faster than json_decode()";
} else {
    echo 'Unpossible!';
}
    echo '<BR>';
//  Compare them
if ( $jsonSize < $phpSize )
{
    echo "json_encode() string was roughly " . number_format( ($phpSize / $jsonSize - 1 ) * 100, 2 ) . "% smaller than serialize()";
}
else if ( $phpSize < $jsonSize )
{
    echo "serialize() string was roughly " . number_format( ($jsonSize / $phpSize - 1 ) * 100, 2 ) . "% smaller than json_encode()";
} else {
    echo 'Unpossible!';
}

मैंने PHP 5.4.12 के साथ एक समान परीक्षण किया है और समान परिणाम पाए हैं: {संयुक्त राष्ट्र,} क्रमबद्ध तेज है। मेरा डेटा हैश नेस्टेड 3 लेवल डीप (900k serialized) है।
sorpigal

6

मैंने एक छोटा बेंचमार्क भी बनाया। मेरे परिणाम समान थे। लेकिन मुझे डिकोड प्रदर्शन की आवश्यकता है। जहां मैंने देखा, जैसे ऊपर के कुछ लोगों ने कहा है, unserializeकी तुलना में तेज है json_decodeunserializeलगभग 60-70% json_decodeसमय लगता है। इसलिए निष्कर्ष काफी सरल है: जब आपको एन्कोडिंग में उपयोग की json_encodeआवश्यकता होती है, तो डिकोडिंग, उपयोग करते समय आपको प्रदर्शन की आवश्यकता होती है unserialize। क्योंकि आप उन दो फ़ंक्शंस को मर्ज नहीं कर सकते हैं जिन्हें आपको एक चुनाव करना है जहाँ आपको अधिक प्रदर्शन की आवश्यकता है।

छद्म में मेरा बेंचमार्क:

  • कुछ यादृच्छिक कुंजियों और मूल्यों के साथ सरणी $ गिरफ्तार को परिभाषित करें
  • x <100 के लिए; एक्स ++; $ गिरफ्तारी का क्रम और json_encode array_rand देखें
  • y के लिए <1000; y ++; json_decode json एन्कोडेड स्ट्रिंग - calc time
  • y के लिए <1000; y ++; क्रमबद्ध स्ट्रिंग - कैल्क समय को अनसुना करें
  • परिणाम जो तेजी से था गूंज

पुनर्विवाह पर: unserialize ने 4 बार json_decode पर 96 बार जीत हासिल की। 2.5ms से अधिक लगभग 1.5ms का एक लाभ के साथ।


3

इससे पहले कि आप अपना अंतिम निर्णय लें, ध्यान रखें कि JSON प्रारूप सहयोगी सरणियों के लिए सुरक्षित नहीं है - json_decode()इसके बजाय उन्हें वस्तुओं के रूप में वापस कर देंगे:

$config = array(
    'Frodo'   => 'hobbit',
    'Gimli'   => 'dwarf',
    'Gandalf' => 'wizard',
    );
print_r($config);
print_r(json_decode(json_encode($config)));

आउटपुट है:

Array
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)
stdClass Object
(
    [Frodo] => hobbit
    [Gimli] => dwarf
    [Gandalf] => wizard
)

वास्तव में, आप सही हैं। मेरा मतलब है, यह है जावास्क्रिप्ट वस्तु afterall अंकन! शुक्र है, अगर आप जानते हैं कि आप जो प्रयोग कर रहे हैं, json_encodeवह एक साहचर्य सरणी था, तो आप इसे आसानी से एक सरणी में वापस ला सकते हैं जैसे: $json = json_encode($some_assoc_array); $back_to_array = (array)json_decode($json);इसके अलावा यह नोट करना अच्छा है कि आप PHP में सरणियों के समान वस्तुओं का उपयोग कर सकते हैं ताकि एक विशिष्ट परिदृश्य में, एक भी अंतर नहीं पता होगा। हालांकि अच्छी बात है!
काइलफ्रिस

30
@toomuchphp, क्षमा करें, लेकिन आप गलत हैं। Json_decode 'bool $ assoc = false' के लिए एक दूसरा पैरामीटर है जो json_decode एक सरणी का उत्पादन करता है। @KyleFarris, यह भी टाइपकास्ट से सरणी के लिए तेजी से होना चाहिए।
जनपियो

उत्तर सही नहीं है। फ़ंक्शन के दूसरे पैरामीटर के रूप में सही का उपयोग करते समय, json_decode () ऑब्जेक्ट्स के बजाय साहचर्य सरणियों को लौटाएगा।
मार्विन सालडिंगर

3

सबसे पहले, मैंने स्क्रिप्ट को कुछ और बेंचमार्किंग करने के लिए बदल दिया (और सिर्फ 1 के बजाय 1000 रन भी किया):

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);

$totalJsonTime = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;

for ($i = 0; $i < 1000; $i++) {
    // Time json encoding
    $start = microtime(true);
    $json = json_encode($testArray);
    $jsonTime = microtime(true) - $start;
    $totalJsonTime += $jsonTime;

    // Time serialization
    $start = microtime(true);
    $serial = serialize($testArray);
    $serializeTime = microtime(true) - $start;
    $totalSerializeTime += $serializeTime;

    if ($jsonTime < $serializeTime) {
        $totalJsonWins++;
    }
}

$totalSerializeWins = 1000 - $totalJsonWins;

// Compare them
if ($totalJsonTime < $totalSerializeTime) {
    printf("json_encode() (wins: $totalJsonWins) was roughly %01.2f%% faster than serialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
    printf("serialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_encode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}

$totalJsonTime = 0;
$totalJson2Time = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;

for ($i = 0; $i < 1000; $i++) {
    // Time json decoding
    $start = microtime(true);
    $orig = json_decode($json, true);
    $jsonTime = microtime(true) - $start;
    $totalJsonTime += $jsonTime;

    $start = microtime(true);
    $origObj = json_decode($json);
    $jsonTime2 = microtime(true) - $start;
    $totalJson2Time += $jsonTime2;

    // Time serialization
    $start = microtime(true);
    $unserial = unserialize($serial);
    $serializeTime = microtime(true) - $start;
    $totalSerializeTime += $serializeTime;

    if ($jsonTime < $serializeTime) {
        $totalJsonWins++;
    }
}

$totalSerializeWins = 1000 - $totalJsonWins;


// Compare them
if ($totalJsonTime < $totalSerializeTime) {
    printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
    printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_decode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}

// Compare them
if ($totalJson2Time < $totalSerializeTime) {
    printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJson2Time - 1) * 100);
} else {
    printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than array json_decode()\n", ($totalJson2Time / $totalSerializeTime - 1) * 100);
}

function fillArray( $depth, $max ) {
    static $seed;
    if (is_null($seed)) {
        $seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
    }
    if ($depth < $max) {
        $node = array();
        foreach ($seed as $key) {
            $node[$key] = fillArray($depth + 1, $max);
        }
        return $node;
    }
    return 'empty';
}

मैंने PHP 7 के इस निर्माण का उपयोग किया:

PHP 7.0.14 (cli) (निर्मित: जनवरी 18 2017 19:13:23) (NTS) कॉपीराइट (c) 1997-2016 PHP समूह Zend इंजन v3.0.0, कॉपीराइट (c) 1998-2016 Zend OPcache के साथ Zend Technologies v7.0.14, कॉपीराइट (c) 1999-2016, Zend Technologies द्वारा

और मेरे परिणाम थे:

क्रमबद्ध करें () (जीतता है: 999) json_encode () unserialize () (जीतता है: 987) की तुलना में लगभग 10.98% अधिक तेज था, json_decode () unserialize () (जीत: 987) की तुलना में मोटे तौर पर सरणी json_decode से 48.35% अधिक तेज़ था। ()

तो स्पष्ट रूप से , सीरियलाइज़ / अनसेरीलाइज़ सबसे तेज़ तरीका है, जबकि json_encode / decode सबसे पोर्टेबल है।

यदि आप एक परिदृश्य पर विचार करते हैं, जहां आप धारावाहिक डेटा 10x या उससे अधिक बार पढ़ते / लिखते हैं, तो आपको गैर-PHP सिस्टम से भेजने या प्राप्त करने की आवश्यकता होती है, तो आप क्रमिक रूप से उपयोग करने के लिए बेहतर हैं / सीरीज़ का उपयोग न करें और इसे क्रमांकन से पहले json_encode या json_decode करें समय के हिसाब से।


2

यहां परिणाम देखें (जेएस कोड बॉक्स में PHP कोड डालकर हैक के लिए खेद है):

http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/

परिणाम: serialize()और unserialize()भिन्न आकार के सरणियों पर PHP 5.4 में काफी तेज हैं।

मैंने json_encode बनाम serialize और json_decode बनाम unserialize की तुलना करने के लिए वास्तविक विश्व डेटा पर एक परीक्षण स्क्रिप्ट बनाई। परीक्षण उत्पादन ई-कॉमर्स साइट में एक के कैशिंग सिस्टम पर चलाया गया था। यह केवल डेटा को पहले से ही कैश में लेता है, और सभी डेटा को एनकोड / डीकोड (या क्रमबद्ध / गैर-व्यवस्थित) करने के लिए समय का परीक्षण करता है और मैं इसे आसानी से टेबल देखने के लिए डाल देता हूं।

मैंने इसे PHP 5.4 साझा होस्टिंग सर्वर पर चलाया।

परिणाम बहुत निर्णायक थे कि इन बड़े से छोटे डेटा सेटों के लिए क्रमबद्धता और गैर-व्याख्याता स्पष्ट विजेता थे। विशेष रूप से मेरे उपयोग के मामले में, कैशिंग सिस्टम के लिए json_decode और unserialize सबसे महत्वपूर्ण हैं। अनसेरिज़ल यहाँ लगभग सर्वव्यापी विजेता था। यह आम तौर पर 2 से 4 गुना (कभी-कभी 6 या 7 बार) जितना तेज होता है जितना कि json_decode।

@ पीटर-बेली से परिणामों में अंतर को ध्यान में रखना दिलचस्प है।

परिणाम उत्पन्न करने के लिए PHP कोड का उपयोग यहां किया गया है:

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

function _count_depth($array)
{
    $count     = 0;
    $max_depth = 0;
    foreach ($array as $a) {
        if (is_array($a)) {
            list($cnt, $depth) = _count_depth($a);
            $count += $cnt;
            $max_depth = max($max_depth, $depth);
        } else {
            $count++;
        }
    }

    return array(
        $count,
        $max_depth + 1,
    );
}

function run_test($file)
{
    $memory     = memory_get_usage();
    $test_array = unserialize(file_get_contents($file));
    $memory     = round((memory_get_usage() - $memory) / 1024, 2);

    if (empty($test_array) || !is_array($test_array)) {
        return;
    }

    list($count, $depth) = _count_depth($test_array);

    //JSON encode test
    $start            = microtime(true);
    $json_encoded     = json_encode($test_array);
    $json_encode_time = microtime(true) - $start;

    //JSON decode test
    $start = microtime(true);
    json_decode($json_encoded);
    $json_decode_time = microtime(true) - $start;

    //serialize test
    $start          = microtime(true);
    $serialized     = serialize($test_array);
    $serialize_time = microtime(true) - $start;

    //unserialize test
    $start = microtime(true);
    unserialize($serialized);
    $unserialize_time = microtime(true) - $start;

    return array(
        'Name'                   => basename($file),
        'json_encode() Time (s)' => $json_encode_time,
        'json_decode() Time (s)' => $json_decode_time,
        'serialize() Time (s)'   => $serialize_time,
        'unserialize() Time (s)' => $unserialize_time,
        'Elements'               => $count,
        'Memory (KB)'            => $memory,
        'Max Depth'              => $depth,
        'json_encode() Win'      => ($json_encode_time > 0 && $json_encode_time < $serialize_time) ? number_format(($serialize_time / $json_encode_time - 1) * 100, 2) : '',
        'serialize() Win'        => ($serialize_time > 0 && $serialize_time < $json_encode_time) ? number_format(($json_encode_time / $serialize_time - 1) * 100, 2) : '',
        'json_decode() Win'      => ($json_decode_time > 0 && $json_decode_time < $serialize_time) ? number_format(($serialize_time / $json_decode_time - 1) * 100, 2) : '',
        'unserialize() Win'      => ($unserialize_time > 0 && $unserialize_time < $json_decode_time) ? number_format(($json_decode_time / $unserialize_time - 1) * 100, 2) : '',
    );
}

$files = glob(dirname(__FILE__) . '/system/cache/*');

$data = array();

foreach ($files as $file) {
    if (is_file($file)) {
        $result = run_test($file);

        if ($result) {
            $data[] = $result;
        }
    }
}

uasort($data, function ($a, $b) {
    return $a['Memory (KB)'] < $b['Memory (KB)'];
});

$fields = array_keys($data[0]);
?>

<table>
    <thead>
    <tr>
        <?php foreach ($fields as $f) { ?>
            <td style="text-align: center; border:1px solid black;padding: 4px 8px;font-weight:bold;font-size:1.1em"><?= $f; ?></td>
        <?php } ?>
    </tr>
    </thead>

    <tbody>
    <?php foreach ($data as $d) { ?>
        <tr>
            <?php foreach ($d as $key => $value) { ?>
                <?php $is_win = strpos($key, 'Win'); ?>
                <?php $color = ($is_win && $value) ? 'color: green;font-weight:bold;' : ''; ?>
                <td style="text-align: center; vertical-align: middle; padding: 3px 6px; border: 1px solid gray; <?= $color; ?>"><?= $value . (($is_win && $value) ? '%' : ''); ?></td>
            <?php } ?>
        </tr>
    <?php } ?>
    </tbody>
</table>

1

सिर्फ एक फी - यदि आप JSON की तरह पढ़ने और समझने में आसान कुछ के लिए अपने डेटा को क्रमबद्ध करना चाहते हैं, लेकिन अधिक संपीड़न और उच्च प्रदर्शन के साथ, आपको मैसेजपैक की जांच करनी चाहिए


2
अगर यह सिर्फ एक फी है, तो आप इसे एक टिप्पणी के रूप में बेहतर ढंग से रख सकते हैं।
टेकनोफाइल

0

JSON बेहतर है यदि आप डेटा का बैकअप लेना चाहते हैं और इसे अलग मशीन पर या एफ़टीपी के माध्यम से पुनर्स्थापित करना चाहते हैं।

उदाहरण के लिए, यदि आप विंडोज सर्वर पर डेटा स्टोर करते हैं, तो इसे एफ़टीपी के माध्यम से डाउनलोड करें और लिनक्स पर इसे फिर से इंस्टॉल करें, यह चरचर री-एन्कोडिंग के कारण और अधिक काम नहीं कर सकता है, क्योंकि सीरियलाइज़ स्ट्रिंग्स की लंबाई और यूनोड में संग्रहीत करता है > UTF-8 ट्रांसकोडिंग कुछ 1 बाइट चरचर एल्गोरिथ्म क्रैश बनाते हुए 2 बाइट्स बन सकती है।


0

THX - इस बेंचमार्क कोड के लिए:

सरणी के लिए मेरे परिणाम मैं विन्यास के लिए उपयोग कर रहे हैं जैसे फॉलोवर्स: JSON 0.0031511783599854 सेकंड में एन्कोडेड
PHP 0.0037961006164551 सेकंड में क्रमबद्ध किया
json_encode()गया, लगभग 20.47% serialize() JSON की तुलना में अधिक तेजी से 0.00358413128447 सेकंड
में एन्कोड किया
unserialize()गया था , जोकि 0.0035839080810547 सेकंड में तेजी से क्रमिक रूप से 97.66% तेजी से प्रसारित हुआ।json_encode()

इसलिए - इसे अपने डेटा पर परीक्षण करें।


आपका मतलब है json_decode () "unserialize () में लगभग 97.66% json_encode ()" की तुलना में तेज़ है, हाँ?
मेज़ान-उद-दीन

0

अगर लोग यहाँ क्या कहते हैं, यह समझने के लिए, json_decode / encode serialize / unserialize BUT से अधिक तेज़ लगता है यदि आप var_dump करते हैं तो serialized ऑब्जेक्ट का प्रकार बदल जाता है। यदि किसी कारण से आप टाइप रखना चाहते हैं, तो क्रमबद्ध होकर जाएं!

(उदाहरण stdClass बनाम सरणी के लिए प्रयास करें)

serialize / unserialize:

Array cache:
array (size=2)
  'a' => string '1' (length=1)
  'b' => int 2
Object cache:
object(stdClass)[8]
  public 'field1' => int 123
This cache:
object(Controller\Test)[8]
  protected 'view' => 

json encode / decode

Array cache:
object(stdClass)[7]
  public 'a' => string '1' (length=1)
  public 'b' => int 2
Object cache:
object(stdClass)[8]
  public 'field1' => int 123
This cache:
object(stdClass)[8]

जैसा कि आप देख सकते हैं json_encode / decode सभी को stdClass में रूपांतरित करता है, जो कि अच्छी, वस्तु की जानकारी नहीं खोया है ... इसलिए आवश्यकताओं के आधार पर निर्णय लें, खासकर अगर यह केवल सरणियाँ नहीं है ...


बस एक नोट: अधिकांश अन्य उत्तर कहते हैं कि सीरियलाइज़ / अनसेरीलाइज़ करना तेज़ है।
Ecker00

-3

मैं आपको सुपर कैश का उपयोग करने का सुझाव दूंगा, जो एक फ़ाइल कैश तंत्र है जो उपयोग नहीं करेगा json_encodeया serialize। यह उपयोग करने के लिए सरल है और अन्य PHP कैश तंत्र की तुलना में वास्तव में तेज़ है।

https://packagist.org/packages/smart-php/super-cache

उदाहरण के लिए:

<?php
require __DIR__.'/vendor/autoload.php';
use SuperCache\SuperCache as sCache;

//Saving cache value with a key
// sCache::cache('<key>')->set('<value>');
sCache::cache('myKey')->set('Key_value');

//Retrieving cache value with a key
echo sCache::cache('myKey')->get();
?>

-1। हालांकि यह एक बेहतर समाधान हो सकता है, लेकिन इस जवाब का कोई भी हिस्सा वास्तव में ओपी के सवाल का जवाब नहीं देता है। भविष्य में, शायद सवाल का जवाब देने की कोशिश करें, लेकिन नीचे एक सुझाव छोड़ दें कि एक वैकल्पिक समाधान जांच के लायक हो सकता है।
स्टारबेम्रेनबोब्लाब्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.