الطريقة المفضلة لتخزين PHP المصفوفات (json_encode مقابل تسلسل)

StackOverflow https://stackoverflow.com/questions/804045

سؤال

أحتاج إلى متجر متعدد الأبعاد النقابي من البيانات في ملف ثابت لأغراض التخزين المؤقت.قد تأتي أحيانا عبر تحتاج إلى تحويل إلى سلمان للاستخدام في تطبيقات الويب ولكن الغالبية العظمى من الوقت سوف تكون باستخدام مجموعة مباشرة في PHP.

سيكون أكثر كفاءة لتخزين مجموعة JSON أو PHP تسلسل مجموعة في ملف نصي ؟ لقد نظرت حولي و يبدو أن في أحدث إصدارات PHP (5.3), json_decode هو في الواقع أسرع من unserialize.

أنا حاليا يميل نحو تخزين مجموعة JSON كما أشعر به أسهل في القراءة من قبل الإنسان إذا لزم الأمر, يمكن أن تستخدم في كل من PHP و جافا سكريبت مع القليل جدا من الجهد ، من ما قرأت, بل قد يكون أسرع لفك (غير متأكد حول ترميز ، على الرغم من).

لا أحد يعرف من أي عثرات ؟ أي شخص لديه معايير مرجعية جيدة لإظهار مزايا الأداء إما الأسلوب ؟

هل كانت مفيدة؟

المحلول

يعتمد على الأولويات الخاصة بك.

إذا كان الأداء المطلقة في القيادة المميزة, ثم بكل الوسائل استخدام أسرع واحد.فقط تأكد من أن لديك فهم كامل من الخلافات قبل اتخاذ خيار

  • على عكس serialize() تحتاج إلى إضافة المزيد من المعلمة للحفاظ على UTF-8 أحرف يمسها: json_encode($array, JSON_UNESCAPED_UNICODE) (وإلا فإنه يحول UTF-8 أحرف Unicode تسلسلات الهروب).
  • سلمان لن يتذكر ما الكائن الأصلي كان الفصل (هم دائما استعادة حالات stdClass).
  • لا يمكنك النفوذ __sleep() و __wakeup() مع JSON
  • بشكل افتراضي فقط الممتلكات العامة هي تسلسل مع JSON.(في PHP>=5.4 يمكنك تنفيذ JsonSerializable لتغيير هذا السلوك).
  • سلمان هو أكثر المحمولة

و ربما هناك بعض الاختلافات الأخرى لا أستطيع التفكير في هذه اللحظة.

اختبار بسيط السرعة للمقارنة بينهما

<?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';
}

نصائح أخرى

سلمان هو أبسط و أسرع من PHP شكل التسلسل وينبغي أن تستخدم إلا إذا:

  • كنت تخزين متداخلة المصفوفات:json_decode():"هذه الدالة بإرجاع خطأ إذا كان سلمان ترميز البيانات هو أعمق من 127 العناصر."
  • كنت تخزين الأشياء التي تحتاج إلى أن تكون unserialized حسب الفئة الصحيحة
  • أنت تتفاعل مع إصدارات PHP التي لا تدعم json_decode

ولقد كتبت مشاركة حول هذا الموضوع: "<لأ href =" http://techblog.procurios.nl/k/n618/news/view/34972/14863/cache-a-large-array-json -serialize-أو var_export.html "يختلط =" noreferrer "> ذاكرة مخبأة مجموعة كبيرة: JSON، تسلسل أو var_export ؟". في هذا المنصب وتبين أن تسلسل هو الخيار الافضل للشركات الصغيرة وصفائف كبيرة الحجم. لصفائف كبيرة جدا (> 70MB) JSON هو الخيار الأفضل.

قد تكون مهتما أيضا في https://github.com/phadej/igbinary التي تقدم مختلف التسلسل 'محرك' PHP.

بلدي عشوائية/التعسفي 'الأداء' الأرقام باستخدام PHP 5.3.5 على 64bit منصة عرض :

سلمان :

  • سلمان المشفرة في 2.180496931076 ثانية
  • سلمان فك الشفرة في 9.8368630409241 ثانية
  • تسلسل "السلسلة" الحجم :13993

الأم PHP :

  • PHP تسلسل في 2.9125759601593 ثانية
  • PHP unserialized في 6.4348418712616 ثانية
  • تسلسل "السلسلة" الحجم :20769

Igbinary :

  • الفوز igbinary تسلسل في 1.6099879741669 ثانية
  • الفوز igbinrary unserialized في 4.7737920284271 ثانية
  • الفوز تسلسل "السلسلة" الحجم :4467

لذا أسرع igbinary_serialize() و igbinary_unserialize() و يستخدم مساحة أقل على القرص.

لقد استخدمت fillArray(0, 3) المدونة أعلاه, إلا أن مجموعة مفاتيح أطول السلاسل.

igbinary يمكن تخزين نفس أنواع البيانات وكذلك PHP الأم تسلسل يمكن (لذلك لا توجد مشكلة مع الكائنات الخ) و يمكن أن أقول لكم PHP5.3 لاستخدامها التعامل جلسة إذا كنت ترغب في ذلك.

انظر أيضا http://ilia.ws/files/zendcon_2010_hidden_features.pdf وتحديدا الشرائح 14/15/16

و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 أسرع لفك السلسلة.

إذا كنت التخزين المؤقت المعلومات التي سوف تحتاج في نهاية المطاف إلى "تشمل" في وقت لاحق في الوقت المناسب، قد ترغب في محاولة باستخدام <لأ href = "http://us2.php.net/var_export" يختلط = " noreferrer "> var_export . وبهذه الطريقة يستغرق سوى ضرب في "تسلسل" وليس في "unserialize".

وأنا تضاف الاختبار لتشمل أداء unserialization. وهنا ارقام حصلت.

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() 

وهكذا سلمان يبدو أن أسرع لترميز ولكنها بطيئة في فك التشفير. لذلك يمكن أن يتوقف طلبك وما كنت تتوقع أن تفعل أكثر.

حقا موضوع جميل و بعد قراءة بعض الردود, أريد أن أشارك تجاربي في هذا الموضوع.

لدي حالة استخدام بعض "ضخمة" الجدول يحتاج إلى أن الاستعلام تقريبا في كل مرة أتحدث إلى قاعدة البيانات (لا تسأل لماذا مجرد حقيقة).قاعدة بيانات نظام التخزين المؤقت ليس مناسب لأنه لن ذاكرة التخزين المؤقت طلبات مختلفة لذا على الرغم من حول php أنظمة التخزين المؤقت.

حاولت apcu لكنها لم تناسب احتياجات الذاكرة ليست موثوقة بما فيه الكفاية في هذه الحالة.الخطوة التالية كانت ذاكرة التخزين المؤقت إلى ملف مع التسلسل.

الجدول 14355 إدخالات مع 18 الأعمدة ، تلك هي بلدي التجارب و الإحصائيات على قراءة تسلسل ذاكرة التخزين المؤقت:

سلمان:

كما قلت الرئيسية إزعاج مع json_encode/json_decode هو أنه يحول كل شيء إلى StdClass سبيل المثال (أو كائن).إذا كنت بحاجة إلى حلقة ، وتحويلها إلى مجموعة ما عليك ربما لا و نعم انها زيادة التحول الوقت

متوسط الوقت:780.2 ms;استخدام الذاكرة:41.5 MB ؛ ذاكرة التخزين المؤقت حجم الملف:3.8 MB

Msgpack

@القفص يذكر msgpack.جدا الموقع.دعونا محاولة إعطائها نحن العرب ؟

متوسط الوقت:497 ms;استخدام الذاكرة:32MB;ذاكرة التخزين المؤقت حجم الملف:2.8 MB

هذا أفضل ، ولكن يتطلب جديدة الإرشاد ؛ تجميع بعض الأحيان يخشى الناس...

IgBinary

@GingerDog يذكر igbinary.علما بأنني قد وضعت igbinary.compact_strings=Offلأن ما يهمني أكثر عن القراءة العروض من حجم الملف.

متوسط الوقت:411.4 ms;استخدام الذاكرة:36.75 MB ؛ ذاكرة التخزين المؤقت حجم الملف:3.3 MB

أفضل من msg حزمة.لا يزال, هذا يتطلب تجميع أيضا.

serialize/unserialize

متوسط الوقت:477.2 ms;استخدام الذاكرة:36.25 MB ؛ ذاكرة التخزين المؤقت حجم الملف:5.9 MB

أفضل العروض من JSON, اكبر مجموعة هو أبطأ json_decode لكنك بالفعل جديد.

هذه ملحقات الخارجية هي تضييق حجم الملف و يبدو رائعا على الورق.الأرقام لا تكذب*.ما الهدف من تجميع التمديد إذا كنت تحصل على تقريبا نفس النتائج التي كنت مع معيار PHP وظيفة ؟

يمكننا أيضا أن نستنتج أن هذا يتوقف على الاحتياجات الخاصة بك ، سوف تختار شيئا مختلفا من شخص آخر:

  • IgBinary هو لطيف حقا وأداء أفضل من MsgPack
  • Msgpack هو أفضل في ضغط الخاص بك دتس (علما بأنني لم أحاول igbinary المدمجة.سلسلة الخيار).
  • لا أريد تجميع?استخدام المعايير.

هذا هو آخر التسلسل أساليب المقارنة لمساعدتك في اختيار واحد!

*اختبار مع PHPUnit 3.7.31, php 5.5.10 - فقط فك مع معيار hardrive القديم ثنائي النواة وحدة المعالجة المركزية - متوسط أعداد على 10 نفس حالة استخدام اختبارات الإحصائيات الخاصة بك قد تكون مختلفة

يبدو أن تسلسل واحد انا ذاهب الى استخدام لمدة 2 أسباب:

  • وأشار أحدهم إلى أنه unserialize أسرع من json_decode و 'قراءة' القضية يبدو أكثر احتمالا من 'الكتابة' القضية.

  • لدي مشكلة مع json_encode عند وجود سلاسل مع صالح UTF-8 أحرف.عندما يحدث ذلك سلسلة ينتهي فارغة مما تسبب في فقدان المعلومات.

ولقد اختبرت هذا جيدا جدا على معقدة إلى حد ما، أقل ما يقال متداخلة متعددة التجزئة مع جميع أنواع البيانات فيه (سلسلة، NULL، الأعداد الصحيحة)، وتسلسل / انتهى unserialize بشكل أسرع بكثير من 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!';
}

أنا جعلت صغير المعيار أيضا.النتائج هي نفسها.ولكن أنا في حاجة إلى فك الأداء.حيث لاحظت أن بعض الأشخاص المذكورة أعلاه أيضا ، unserialize هو أسرع من json_decode. unserialize يأخذ ما يقرب من 60-70% من json_decode الوقت.وبالتالي فإن الاستنتاج هو بسيط إلى حد ما:عندما كنت في حاجة الأداء في ترميز استخدام json_encode, عندما كنت بحاجة الأداء عند فك استخدام unserialize.لأنه لا يمكن دمج اثنين من المهام التي لديك لجعل خيار حيث كنت بحاجة إلى المزيد من الأداء.

بلدي المعيار في الزائفة:

  • تعريف المصفوفة $arr مع عدد قليل من عشوائية المفاتيح و القيم
  • x < 100;x++;تسلسل json_encode على array_rand من $arr
  • y < 1000;y++;json_decode سلمان ترميز سلسلة - احسب الوقت
  • y < 1000;y++;unserialize تسلسل سلسلة - احسب الوقت
  • صدى النتيجة التي كان أسرع

على أفاراجي:unserialize فاز 96 مرات أكثر من 4 مرات json_decode.مع أفاراجي ما يقرب من 1.5 ms أكثر من 2.5 مللي.

وقبل اتخاذ القرار النهائي الخاص بك، تكون على علم أن شكل 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
)

تحقق من النتائج هنا (آسف هاك وضع كود PHP في شبيبة رمز مربع):

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

النتائج: serialize() و unserialize() على حد سواء بشكل أسرع في PHP 5.4 على المصفوفات متفاوتة الحجم.

أنا قدمت اختبار البرنامج النصي على بيانات العالم الحقيقي مقارنة json_encode مقابل تسلسل json_decode مقابل unserialize.اختبار تشغيل في نظام التخزين المؤقت في إنتاج موقع للتجارة الإلكترونية.ببساطة يأخذ البيانات بالفعل في ذاكرة التخزين المؤقت ، واختبارات مرات تشفير / فك شفرة (أو تسلسل / unserialize) جميع البيانات في وسيلة سهلة لمعرفة الجدول.

ركضت على PHP 5.4 خادم الاستضافة المشتركة.

وكانت النتائج جدا قاطعة أن هذه الكبيرة إلى صغيرة مجموعات البيانات تسلسل unserialize كانت واضحة الفائزين.ولا سيما استخدام الحالة ، json_decode و unserialize هي الأكثر أهمية نظام التخزين المؤقت.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>

وفقط لمعلوماتك - إذا كنت ترغب في إجراء تسلسل البيانات الخاصة بك إلى شيء من السهل قراءتها وفهمها مثل JSON لكن مع مزيد من الضغط والأداء العالي، عليك أن تتحقق من <لأ href = "http://msgpack.org/" يختلط = "نوفولو"> messagepack.

اولا انا غيرت السيناريو أن تفعل أكثر من ذلك القياس (كما تفعل 1000 يعمل بدلا من مجرد 1):

<?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) (بني:Jan 18 عام 2017 19:13:23) ( NTS ) حقوق الطبع والنشر (ج) 1997-2016 PHP مجموعة زند محرك v3.0.0, حقوق الطبع والنشر (ج) 1998-2016 زند التقنيات مع زند OPcache v7.0.14, حقوق الطبع والنشر (ج) 1999-2016 ، زند التقنيات

و كانت النتائج:

تسلسل() (wins:999) تقريبا 10.98% أسرع من json_encode() unserialize() (wins:987) تقريبا 33.26% أسرع من json_decode() unserialize() (wins:987) تقريبا 48.35% أسرع من مجموعة json_decode()

لذلك بوضوح, تسلسل/unserialize هو أسرع طريقة, في حين json_encode/فك شفرة هو أكثر المحمولة.

إذا كنت النظر في السيناريو حيث يمكنك قراءة/كتابة تسلسل البيانات 10 مرات أو أكثر في كثير من الأحيان مما كنت بحاجة إلى إرسال أو استقبال من غير PHP نظام, أنت ما زلت أفضل استخدام تسلسل/unserialize ويكون ذلك json_encode أو json_decode قبل التسلسل من حيث الوقت.

وJSON هو أفضل إذا كنت تريد أن بيانات النسخ الاحتياطي واستعادته على جهاز آخر أو عن طريق FTP.

وعلى سبيل المثال مع تسلسل إذا قمت بتخزين البيانات على خادم ويندوز، تحميل البرنامج عن طريق FTP واستعادتها على لينكس واحدة لا يمكن أن تعمل أي أكثر من ذلك نظرا لتحديثاتك إعادة ترميز، لأن تسلسل يخزن طول الجمل و في يونيكود> UTF-8 الترميز بعض تحديثاتك 1 بايت قد يصبحون 2 بايت تبذل منذ فترة طويلة تحطم الخوارزمية.

وTHX - لهذا الرمز القياسي:

ونتائجي في مجموعة يمكنني استخدام لتكوين كما فالوز: JSON المشفرة في 0.0031511783599854 ثانية
تسلسل PHP في 0.0037961006164551 ثانية
كان json_encode() تقريبا أسرع 20.47٪ من serialize() JSON المشفرة في 0.0070841312408447 ثانية
تسلسل PHP في 0.0035839080810547 ثانية
كان unserialize() تقريبا 97.66٪ أسرع من json_encode()

وهكذا -. اختباره على البيانات الخاصة بك

إذا لSUMM حتى ما يقوله الناس هنا، json_decode / ترميز يبدو أسرع من تسلسل / unserialize BUT إذا كنت تفعل var_dump يتم تغيير نوع الكائن المتسلسلة. إذا لسبب ما كنت تريد أن تبقي نوع، والذهاب مع تسلسل!

و(محاولة على سبيل المثال stdClass مقابل مجموعة)

وتسلسل / 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' => 

وسلمان ترميز / فك

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 / فك شفرة تحويل كافة إلى stdClass، وهي ليست على ما يرام، يعترض المعلومات المفقودة ... وهكذا تقرر على أساس الاحتياجات الخاصة، لا سيما إذا كان ليس فقط صفائف ...

وأود أن أقترح عليك استخدام السوبر ذاكرة التخزين المؤقت، والذي هو آلية ذاكرة التخزين المؤقت الملفات التي لن تستخدم 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();
?>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top