美文网首页
PHP序列化对比(Protobuf&Json)

PHP序列化对比(Protobuf&Json)

作者: Rohn | 来源:发表于2017-07-10 14:18 被阅读641次

概念

测试脚本

  • protobuf schema (test.proto)
message Test {
    optional int32 aaa = 1;
    repeated string bbb = 2;
}
  • 编译test.proto
<?php
/**
 * Test message
 */
class Test extends ProtobufMessage
{
    /* Field index constants */
    const AAA = 1;
    const BBB = 2;

    /* @var array Field descriptors */
    protected static $fields = array(
        self::AAA => array(
            'name' => 'aaa',
            'required' => false,
            'type' => 5,
        ),
        self::BBB => array(
            'name' => 'bbb',
            'repeated' => true,
            'type' => 7,
        ),
    );

    /**
     * Constructs new message container and clears its internal state
     *
     * @return null
     */
    public function __construct()
    {
        $this->reset();
    }

    /**
     * Clears message values and sets default ones
     *
     * @return null
     */
    public function reset()
    {
        $this->values[self::AAA] = null;
        $this->values[self::BBB] = array();
    }

    /**
     * Returns field descriptors
     *
     * @return array
     */
    public function fields()
    {
        return self::$fields;
    }

    /**
     * Sets value of 'aaa' property
     *
     * @param int $value Property value
     *
     * @return null
     */
    public function setAaa($value)
    {
        return $this->set(self::AAA, $value);
    }

    /**
     * Returns value of 'aaa' property
     *
     * @return int
     */
    public function getAaa()
    {
        return $this->get(self::AAA);
    }

    /**
     * Appends value to 'bbb' list
     *
     * @param string $value Value to append
     *
     * @return null
     */
    public function appendBbb($value)
    {
        return $this->append(self::BBB, $value);
    }

    /**
     * Clears 'bbb' list
     *
     * @return null
     */
    public function clearBbb()
    {
        return $this->clear(self::BBB);
    }

    /**
     * Returns 'bbb' list
     *
     * @return string[]
     */
    public function getBbb()
    {
        return $this->get(self::BBB);
    }

    /**
     * Returns 'bbb' iterator
     *
     * @return ArrayIterator
     */
    public function getBbbIterator()
    {
        return new ArrayIterator($this->get(self::BBB));
    }

    /**
     * Returns element from 'bbb' list at given offset
     *
     * @param int $offset Position in list
     *
     * @return string
     */
    public function getBbbAt($offset)
    {
        return $this->get(self::BBB, $offset);
    }

    /**
     * Returns count of 'bbb' list
     *
     * @return int
     */
    public function getBbbCount()
    {
        return $this->count(self::BBB);
    }
}
  • php测试脚本
<?php
/**
 * @name   序列化调研
 * @author Rohn(253133755@qq.com)
 * @date   2017/7/6
 */
include 'pb_proto_test.php';

class SerializeTest
{

    private $test_data = array();
    private $data_json = array();
    private $data_pb = array();

    public $report = array();

    static $str = array(
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
        'g',
        'h',
        'i',
        'j',
        'k',
        'l',
        'm',
        'n',
        'o',
        'p',
        'q',
        'r',
        's',
        't',
        'u',
        'v',
        'w',
        'x',
        'y',
        'z',
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
        'G',
        'H',
        'I',
        'J',
        'K',
        'L',
        'M',
        'N',
        'O',
        'P',
        'Q',
        'R',
        'S',
        'T',
        'U',
        'V',
        'W',
        'X',
        'Y',
        'Z',
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        0,
        '_',
        '!',
        '@',
        '#',
        '$',
        '%',
        '^',
        '&',
        '*',
        '(',
        ')',
        '-',
        '+',
        '=',
        '阿',
        '萨',
        '德',
        '额',
        '人',
        '哦',
        '吗',
        '从',
        '是',
        '去',
        '吧',
        '你',
        '放',
        '如',
    );

    /**
     * 运行入口
     */
    public function run(){

        $list = array(
            1000,
            3000,
            30000,
            100000,
            300000,
        );
        foreach($list as $test){
            $this->_do_run($test);
        }
        print_r($this->report);
    }

    /**
     * 运行测试数据
     * @param $count
     */
    private function _do_run($count){

        $this->_get_data($count);
        $encode_report  = $this->_encode();
        $decode_report  = $this->_decode();
        $this->report[] = array_merge($encode_report, $decode_report);
    }

    /**
     * 序列化
     * @return array
     */
    private function _encode(){

        //json
        $this->data_json  = null;
        $s_mem            = memory_get_usage();
        $s_time           = microtime(true);
        $this->data_json  = json_encode($this->test_data);
        $e_time           = microtime(true);
        $e_mem            = memory_get_usage();
        $length_json      = number_format(mb_strlen($this->data_json) / 1024, 7, '.', '');
        $encode_meme_json = $e_mem - $s_mem;
        $encode_time_json = $e_time - $s_time;

        //protobuf
        $test_obj      = new Test();
        $this->data_pb = null;
        $test_obj->setAaa($this->test_data['aaa']);
        if(isset($this->test_data['bbb']) && count($this->test_data['bbb']) > 0){
            foreach($this->test_data['bbb'] as $b){
                $test_obj->appendBbb($b);
            }
        }
        $s_mem          = memory_get_usage();
        $s_time         = microtime(true);
        $this->data_pb  = $test_obj->serializeToString();
        $e_time         = microtime(true);
        $e_mem          = memory_get_usage();
        $length_pb      = number_format(mb_strlen($this->data_pb) / 1024, 7, '.', '');
        $encode_meme_pb = $e_mem - $s_mem;
        $encode_time_pb = $e_time - $s_time;
        $test_obj       = null;

        return array(
            'length_js'      => $length_json,
            'length_pb'      => $length_pb,
            'length_p'       => ($length_json - $length_pb) * 100 / $length_pb,
            'encode_mem_js'  => $encode_meme_json,
            'encode_mem_pb'  => $encode_meme_pb,
            'encode_mem_p'   => ($encode_meme_json - $encode_meme_pb) * 100 / $encode_meme_pb,
            'encode_time_js' => $encode_time_json,
            'encode_time_pb' => $encode_time_pb,
            'encode_time_p'  => ($encode_time_json - $encode_time_pb) * 100 / $encode_time_pb,
        );
    }

    /**
     * 解序列化
     * @return array
     */
    private function _decode(){

        //json
        $s_mem            = memory_get_usage();
        $s_time           = microtime(true);
        $d                = json_decode($this->data_json, 1);
        $e_time           = microtime(true);
        $e_mem            = memory_get_usage();
        $decode_meme_json = $e_mem - $s_mem;
        $decode_time_json = $e_time - $s_time;
        $d                = null;

        //protobuf
        $test_obj = new Test();
        $s_mem    = memory_get_usage();
        $s_time   = microtime(true);
        $test_obj->parseFromString($this->data_pb);
        $e_time         = microtime(true);
        $e_mem          = memory_get_usage();
        $decode_meme_pb = $e_mem - $s_mem;
        $decode_time_pb = $e_time - $s_time;
        $test_obj       = null;

        return array(
            'decode_mem_js'  => $decode_meme_json,
            'decode_mem_pb'  => $decode_meme_pb,
            'decode_mem_p'   => ($decode_meme_json - $decode_meme_pb) * 100 / $decode_meme_pb,
            'decode_time_js' => $decode_time_json,
            'decode_time_pb' => $decode_time_pb,
            'decode_time_p'  => ($decode_time_json - $decode_time_pb) * 100 / $decode_time_pb,
        );
    }

    /**
     * 构造数据
     * @param $count
     */
    private function _get_data($count){

        $this->test_data['aaa'] = mt_rand(0, $count);
        for($i = 0; $i < $count; $i++){
            $this->test_data['bbb'][] = $this->get_str(100);
        }
    }

    /**
     * 获得随机字符串
     * @param $length
     * @return string
     */
    private function get_str($length){

        $data  = '';
        $count = count(self::$str);
        for($i = 0; $i < $length; $i++){
            $data .= self::$str[mt_rand(0, $count - 1)];
        }

        return $data;
    }
}

$s = new SerializeTest();
$s->run();

  • 执行测试脚本
    php index.php

  • 输出结果

Array
(
    [0] => Array
        (
            [length_js] => 176.8730469
            [length_pb] => 130.8339844
            [length_p] => 35.188917245877
            [encode_mem_js] => 181280
            [encode_mem_pb] => 134024
            [encode_mem_p] => 35.259356533158
            [encode_time_js] => 0.0026960372924805
            [encode_time_pb] => 0.00014805793762207
            [encode_time_p] => 1720.9339774557
            [decode_mem_js] => 297256
            [decode_mem_pb] => 296552
            [decode_mem_p] => 0.23739512800453
            [decode_time_js] => 0.0033869743347168
            [decode_time_pb] => 0.00016999244689941
            [decode_time_p] => 1892.4263674614
        )

    [1] => Array
        (
            [length_js] => 706.4111328
            [length_pb] => 522.8535156
            [length_p] => 35.106891648105
            [encode_mem_js] => 723528
            [encode_mem_pb] => 535440
            [encode_mem_p] => 35.127745405648
            [encode_time_js] => 0.010690927505493
            [encode_time_pb] => 0.00066089630126953
            [encode_time_p] => 1517.6406926407
            [decode_mem_js] => 1186200
            [decode_mem_pb] => 1185464
            [decode_mem_p] => 0.062085394410965
            [decode_time_js] => 0.013932943344116
            [decode_time_pb] => 0.00093817710876465
            [decode_time_p] => 1385.1080050826
        )

    [2] => Array
        (
            [length_js] => 6002.6904297
            [length_pb] => 4443.3632813
            [length_p] => 35.093397718851
            [encode_mem_js] => 6146920
            [encode_mem_pb] => 4550064
            [encode_mem_p] => 35.095242616368
            [encode_time_js] => 0.089380025863647
            [encode_time_pb] => 0.0054750442504883
            [encode_time_p] => 1532.4986936074
            [decode_mem_js] => 10321456
            [decode_mem_pb] => 10320736
            [decode_mem_p] => 0.0069762466552773
            [decode_time_js] => 0.11988496780396
            [decode_time_pb] => 0.0090479850769043
            [decode_time_p] => 1224.9907773386
        )

    [3] => Array
        (
            [length_js] => 23659.4199219
            [length_pb] => 17512.7265625
            [length_p] => 35.098437341915
            [encode_mem_js] => 24227408
            [encode_mem_pb] => 17933072
            [encode_mem_p] => 35.099039361466
            [encode_time_js] => 0.37850999832153
            [encode_time_pb] => 0.025068044662476
            [encode_time_p] => 1409.9302854208
            [decode_mem_js] => 40707576
            [decode_mem_pb] => 40706992
            [decode_mem_p] => 0.0014346429723916
            [decode_time_js] => 0.47448205947876
            [decode_time_pb] => 0.051760911941528
            [decode_time_p] => 816.68025481228
        )

    [4] => Array
        (
            [length_js] => 76635.7978516
            [length_pb] => 56723.3193359
            [length_p] => 35.104572068118
            [encode_mem_js] => 78475224
            [encode_mem_pb] => 58084816
            [encode_mem_p] => 35.104540918232
            [encode_time_js] => 1.1786558628082
            [encode_time_pb] => 0.0988929271698
            [encode_time_p] => 1091.850516048
            [decode_mem_js] => 129246120
            [decode_mem_pb] => 129245304
            [decode_mem_p] => 0.00063135756174166
            [decode_time_js] => 1.509269952774
            [decode_time_pb] => 0.13635492324829
            [decode_time_p] => 1006.8686900478
        )
)

深入了解原理请访问
http://www.jianshu.com/p/ec39f79c0412

相关文章

网友评论

      本文标题:PHP序列化对比(Protobuf&Json)

      本文链接:https://www.haomeiwen.com/subject/wmwyhxtx.html