本篇文章将介绍在数据交换中,常用的序列化方法,并对其进行分析和对比。

  • 定义
  • JSON
    即JavaScript Object Notation,是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。

    serialize
    它是php的一个方法,将变量序列化,返回一个具有变量类型和结构的字符串表达式。

    igbinary
    php序列化的一个代替方案,并未加入到php的标准库中。该序列话主要是对时间和空间消耗的文字表述,igbinary提供结构紧凑二进制形式。

    msgpack
    全程MessagePack,是一个基于二进制高效的对象序列化类库,可用于跨语言通信,它可以像JSON那样,在许多种语言之间交换结构对象,支持Python、Ruby、Java、C/C++等众多语言。

  • 安装
  • 由于igbinary和msgpack不是php自带的,因此我们需要先进行安装。
    igbinary具体安装如下:

    #下载igbinary安装包
    root@localhost [~]# wget https://nodeload.github.com/phadej/igbinary/zip/master
    root@localhost [~]# tar -zxvf master
    root@localhost [~]# cd igbinary-master/
    root@localhost [~]# phpize
    root@localhost [~]# ./configure CFLAGS="-O2 -g" --enable-igbinary
    root@localhost [~]# make
    root@localhost [~]# make install
    #修改php配置文件,增加一行,重启
    extension=igbinary.so

    msgpack具体安装如下:

    #下载msgpack安装包
    root@localhost [~]# wget http://pecl.php.net/get/msgpack-0.5.6.tgz
    root@localhost [~]# tar -zxvf msgpack-0.5.6.tgz
    root@localhost [~]# cd msgpack-0.5.6/
    root@localhost [~]# phpize
    root@localhost [~]# ./configure
    root@localhost [~]# make
    root@localhost [~]# make install
    #修改php配置文件,增加一行,重启
    extension=igbinary.so
  • 简单运行
  • 为了便于了解它们的数据结构,编写测试代码,输出格式化后的数据。

    <?php
    $data = array(  'name' => 'Shy Song',
                    'age' => 25,
                    'country' => 'China'
                 );
    $json_data = json_encode($data);
    $serialize_data = serialize($data);
    $igbinary_data = igbinary_serialize($data);
    $msgpack_data = msgpack_pack($data);
    print 'JSON: ' . $json_data;
    print 'length: ' . strlen($json_data);
    print 'serialize: ' . $serialize_data;
    print 'length: ' . strlen($serialize_data);
    print 'igbinary: ' . $igbinary_data;
    print 'length: ' . strlen($igbinary_data);
    print 'msgpack: ' . $msgpack_data;
    print 'length: ' . strlen($msgpack_data);

    输出结果如下:

    JSON:
    {"name":"Shy","age":25,"country":"China"}
    length: 41
    serialize:
    a:3:{s:4:"name";s:3:"Shy";s:3:"age";i:25;s:7:"country";s:5:"China";}
    length: 68
    igbinary:
    nameShyagecountryChina;
    length: 40
    msgpack:
    ��name�Shy�age�country�China
    length: 29

    可以看出,msgpack最短但不可读,serialize最长,json和igbinary长度差不多。注意,igbinary的实际数据比输出结果要长,只是不可显示。

  • 性能对比
  • 编写代码,对比不同数据转换所耗费的时间。

    <?php
    $info = array(  'name' => 'Shy',
                    'age' => 25,
                    'country' => 'China'
                 );
    $data = array();
    for($i = 0; $i < 1000; $i++)
    {
        $data[$i] = $info;
    }
    $time_start = microtime(true);
    for($i = 0; $i < 10000; $i++)
    {
        $json_data = json_encode($data);
        #$serialize_data = serialize($data);
        #$igbinary_data = igbinary_serialize($data);
        #$msgpack_data = msgpack_pack($data);
    }
    $time_end = microtime(true);
    echo round($time_end - $time_start, 3);

    得到的结果是,JSON 7.232秒,serialize 11.887秒,igbinary 1.156秒,msgpack 1.148秒。

    之后,将数组姓名和国家改成中国进行测试,以及调整数组长度测试,得到一系列测试结果,如下:

    测试场景 JSON serialize igbinary msgpack
    1000长度英文数组 7.232秒 11.887秒 1.156秒 1.148秒
    1000长度中文数组 7.668秒 11.613秒 1.152秒 1.160秒
    100000长度超大数组 78.279秒 135.555秒 11.533秒 11.530秒
    大维度数组 19.249秒 120.385秒 0.003秒 0.003秒

    通过以上对比,我们可以看到性能方面igbinary和msgpack远远优于JSON和serialize,且当面对深度的多维数组时,json和serialize的性能会大幅度下降。

  • 总结
  • 1. JSON是最为常用的、跨语言的数据传输方案,数据转换灵活,转换后的格式依旧保持清晰、可读,适用于通常情况下的数据传输。
    2. serialize常用于方法、类的序列化,适用于在不同程序间进行函数的传输。
    3. msgpack比JSON更快速也更轻巧,压缩后的数据格式会比json小,但是其可读性低,适用于对传输性能要求高且不关心数据格式的场景使用。
    4. igbinary为结构化数据,速度快,内存占用低,适用于memcached、redis等类似的基于内存的储量序列化的数据。

    注:以上所有数据分析,均为本人在阿里云服务器上面进行的测试,不同机器可能测试的具体数据结果不同,但是不影响对比分析。
    最后,附上ugg同学提供的另一个性能对比,以作参考。