1. 程式人生 > >【宇潤日常瘋測-003】PHP 序列化和 JSON 哪個更好?

【宇潤日常瘋測-003】PHP 序列化和 JSON 哪個更好?

有了 Swoole 以後,用我們熟悉的 PHP 就可以很方便地開發網路通訊應用。有時候我們系統內部需要交換資料,那麼,這時候問題來了,網路通訊的資料格式是選擇 JSON 還是 serialize 呢?

一通分析猛如虎

JSON 顯然更通用,不用關心通訊雙方是什麼語言。

serialize 也不差,它可以將物件狀態儲存,在反序列化時恢復狀態。這是 JSON 所不能比的。但是每種語言自身的 serialize 幾乎都不通用,跨語言通訊行不通。

所以,這裡我們暫時只先考慮 PHP 內部系統間的資料交換,用哪個更好呢?

這個問題,沒有親自測試過的人,肯定不能拍著胸脯說出答案。因為我也看了,網上對這兩種資料格式公說紛紜。

那麼,我也來親自驗證一下吧。當然,結果僅供參考,請根據實際場景選擇適合你們專案的資料格式。

程式碼驗證

首先我要說明一下,我選擇了幾種資料結構,有陣列、巢狀陣列、物件、物件陣列、某API大量資料,儘管挺多的,但是還是有可能考慮不全面。

首先我使用了一個公開api來獲取一個大量資料,儲存為data.json檔案,api地址:https://www.apiopen.top/journalismApi

我的環境:

WSL + PHP 7.2.12

然後跑下面的程式碼:

<?php
define('TEST_COUNT', 10000);

function test($name, $callable)
{
    $time = microtime(true);
    $callable();
    echo $name, ' time: ', microtime(true) - $time, 's', PHP_EOL;
}

function myTest($name, $data)
{
    echo $name, ':', PHP_EOL;
    $encodeResult = json_encode($data);
    echo 'json_encode size: ', strlen($encodeResult), PHP_EOL;
    test('json_encode', function() use($data){
        for($i = 0; $i < TEST_COUNT; ++$i)
        {
            json_encode($data);
        }
    });
    test('json_decode', function() use($encodeResult){
        for($i = 0; $i < TEST_COUNT; ++$i)
        {
            json_encode($encodeResult);
        }
    });

    $encodeResult = serialize($data);
    echo 'serialize size: ', strlen($encodeResult), PHP_EOL;
    test('serialize', function() use($data){
        for($i = 0; $i < TEST_COUNT; ++$i)
        {
            serialize($data);
        }
    });
    test('unserialize', function() use($encodeResult){
        for($i = 0; $i < TEST_COUNT; ++$i)
        {
            unserialize($encodeResult);
        }
    });
    echo '----------------', PHP_EOL;
}

function test1()
{
    $data = [
        'id'    =>  1,
        'name'  =>  '宇潤',
    ];
    myTest(__FUNCTION__, $data);
}

function test2()
{
    $data = [
        [
            'id'    =>  1,
            'name'  =>  '宇潤',
        ],
        [
            'id'    =>  2,
            'name'  =>  '路人',
        ],
        [
            'id'    =>  3,
            'name'  =>  '老王',
        ],
        [
            'id'    =>  4,
            'name'  =>  '烏龜',
        ],
        [
            'id'    =>  5,
            'name'  =>  '甲魚',
        ],
    ];
    myTest(__FUNCTION__, $data);
}

function test3()
{
    $data = new stdClass;
    $data->name = 'testName';
    $data->age = 250;
    $data->hash = md5(250);
    myTest(__FUNCTION__, $data);
}

function test4()
{
    $data = [];
    for($i = 0; $i < 10; ++$i)
    {
        $obj = new stdClass;
        $obj->name = 'testName' . $i;
        $obj->age = $i;
        $obj->hash = md5($i);
        $data[] = $obj;
    }
    myTest(__FUNCTION__, $data);
}

function test5()
{
    $data = json_decode(file_get_contents(__DIR__ . '/data.json'));
    myTest(__FUNCTION__, $data);
}

function test6()
{
    $data = json_decode(file_get_contents(__DIR__ . '/data.json'), true);
    myTest(__FUNCTION__, $data);
}

test1();
test2();
test3();
test4();
test5();
test6();

結果:

test1:
json_encode size: 30
json_encode time: 0.0017490386962891s
json_decode time: 0.0014638900756836s
serialize size: 43
serialize time: 0.0014791488647461s
unserialize time: 0.0049228668212891s
----------------
test2:
json_encode size: 156
json_encode time: 0.0059618949890137s
json_decode time: 0.0056710243225098s
serialize size: 241
serialize time: 0.0055370330810547s
unserialize time: 0.019223928451538s
----------------
test3:
json_encode size: 71
json_encode time: 0.0030298233032227s
json_decode time: 0.0024290084838867s
serialize size: 112
serialize time: 0.0026299953460693s
unserialize time: 0.010625839233398s
----------------
test4:
json_encode size: 711
json_encode time: 0.025734186172485s
json_decode time: 0.024907827377319s
serialize size: 1157
serialize time: 0.022525072097778s
unserialize time: 0.083372831344604s
----------------
test5:
json_encode size: 63741
json_encode time: 1.7440521717072s
json_decode time: 1.8029508590698s
serialize size: 64325
serialize time: 0.82009410858154s
unserialize time: 2.8286778926849s
----------------
test6:
json_encode size: 63741
json_encode time: 1.7795789241791s
json_decode time: 1.7996029853821s
serialize size: 62193
serialize time: 0.69928193092346s
unserialize time: 1.822273015976s
----------------

結論

  • 資料小的情況下,使用 JSON 在體積和效能上更為佔優勢
  • 當資料大的情況下,使用物件 + serialize 效能更好,體積也稍小
  • unserialize 總是比 serialize 成噸地慢
  • 總的來講,JSON 還是比較穩的,如果沒有恢復物件狀態需求的話

結論僅供參考,測試的資料種類還是太少,請結合自身場景來測試和選擇