【宇潤日常瘋測-003】PHP 序列化和 JSON 哪個更好?
阿新 • • 發佈:2018-12-10
有了 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
還是比較穩的,如果沒有恢復物件狀態需求的話
結論僅供參考,測試的資料種類還是太少,請結合自身場景來測試和選擇