本篇文章将介绍在数据交换中,常用的序列化方法,并对其进行分析和对比。
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具体安装如下:
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具体安装如下:
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
为了便于了解它们的数据结构,编写测试代码,输出格式化后的数据。
$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);
输出结果如下:
{"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的实际数据比输出结果要长,只是不可显示。
编写代码,对比不同数据转换所耗费的时间。
$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同学提供的另一个性能对比,以作参考。
Leave a Reply