【宇润日常疯测-003】PHP 序列化和 JSON 哪个更好?

815 阅读4分钟
有了 Swoole 以后,用我们熟悉的 PHP 就可以很方便地开发网络通信应用。有时候我们系统内部需要交换数据,那么,这时候问题来了,PHP 网络通讯的数据格式是选择 JSON 还是 serialize 呢?

一通分析猛如虎

JSON 显然更通用,不用关心通信双方是什么语言。

serialize 也不差,它可以将对象状态保存,在反序列化时恢复状态。这是 JSON 所不能比的。但是每种语言自身的 serialize 几乎都不通用,跨语言通讯行不通。

所以,这里我们暂时只先考虑 PHP 内部系统间的数据交换,用哪个更好呢?

这个问题,没有亲自测试过的人,肯定不能拍着胸脯说出答案。因为我也看了,网上对这两种数据格式公说纷纭。

那么,我也来亲自验证一下吧。当然,结果仅供参考,请根据实际场景选择适合你们项目的数据格式。

代码验证

首先我要说明一下,我选择了几种数据结构,有数组、嵌套数组、对象、对象数组、某API大量数据,尽管挺多的,但是还是有可能考虑不全面。

首先我使用了一个公开api来获取一个大量数据,保存为data.json文件,api地址:www.apiopen.top/journalismA…

我的环境:

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 还是比较稳的,如果没有恢复对象状态需求的话

结论仅供参考,测试的数据种类还是太少,请结合自身场景来测试和选择