新型序列化类库MessagePack,⽐JSON更快、更⼩的格式MessagePack 是个什么东东?先来看⼀段官⽅的解释:
MessagePack is an efficient binary rialization format. It lets you exchange data among multiple languages like JSON. But it’s faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themlves.
春天的成语MessagePack 是⼀个⾼效的⼆进制序列化格式。它让你像JSON⼀样可以在各种语⾔之间交换数据。但是它⽐JSON更快、更⼩。⼩的整数会被编码成⼀个字节,短的字符串仅仅只需要⽐它的长度多⼀字节的⼤⼩。
官⽅⽤⼀句话总结了这个东东:
It’s like JSON.
but fast and small.
最初研究MessagePack ⼤概是两年前了,还开了个讲座给⼤家讲MessagePack是个什么东西,⼤概⽤在什么场合,它是不是给Javascript⽤的之类的。但是两年过去了,由于博客平台⽼系统太多,以⾄于这个协议⼀直没有能推进使⽤。后来,redis宣布⽀持MessagePack格式,以及pintrest等公司,也在积极
得使⽤这个协议进⾏开发,说明这个格式确实有很多先进性。
MessagePack、protocol buffers、json的速度对⽐
这张图⽚是以前MessagePack 官⽅⽹站的⾸页图⽚,数字对⽐确实很能反映问题,笔者不是很了解protocol buffers,XML⼜太⽼⼟了,就跳过他们俩了,只讨论JSON和MessagePack了。
为啥会⼩?
先⼤概说下MessagePack 为啥会⽐JSON⼩吧,先来段json:
{“name“:”heyue“,”x“:”\u7537“,”company“:”sina“,”age“:30}
这个json长度为57字节,但是为了表⽰这个数据结构(所有标红⾊的地⽅就是他为了表⽰这个数据结构⽽不得不添加的),它⽤了23个字节(就是那些⼤括号、引号、冒号之类的,他们是⽩⽩多出来的)。⼤家可以去 上看看json的数据标⽰定义。
换成MessagePack,我只能给⼤家贴代码和结果了,38字节:
1 2 3 4 5 6 7 8 9 10<?php
水瓶座的女明星
$arr
=
array
其实我真的很在乎
(
'name'
=> "heyue"
,
'x'
=>
'男'
,
'company' =>
'sina'
,
'age'
=>30);
echo "Json:"
.
strlen
(json_encode( $arr
)).
"\n"
11 12 13 14 15 16 17 18 19 20 21 22 23 24"\n"
;
echo "Messagepack:"
.
strlen (msgpack_pack( $arr
)).
"\n"
;
$str
=
"何跃新浪"
;
echo
json_encode( $str
).
"\n"
;
echo
手机服务密码怎么查'json_str:'
.
strlen
(json_encode( $str
)
).
"\n"
;
echo
'MessagePack_str:' .
电脑桌效果图strlen (msgpack_pack( $str
)).
"\n"
;
$str
=
"sina china"
;
echo
json_encode( $str
).
"\n"
;
echo
'json_str:'
.
笔记本电脑录屏
strlen
(json_encode( $str
)).
"\n"
;
echo
'MessagePack_str:' .
strlen (msgpack_pack( $str
)).
"\n"
;
>
我不能给⼤家算⽐例,因为这个得看MessagePack的压缩算法,MessagePack的核⼼压缩⽅式:
2.不⽤表⽰长度的:就是数字之类的,他们天然是定长的,是⽤⼀个字节表⽰后⾯的内容是什么东东,⽐如⽤(0xcc 表⽰这后⾯,是个uint 8,⽤oxcd表⽰后⾯是个uint 16,⽤ 0xca 表⽰后⾯的是个float 32).
3.不定长的:⽐如字符串、数组,类型后⾯加 1~4个字节,⽤来存字符串的长度,如果是字符串长度是256以内的,只需要1个字
节,MessagePack能存的最长的字符串,是(2^32 -1 ) 最长的4G的字符串⼤⼩。
<结构:表⽰特定的⼩单元数据。
5.⾼级结构:MAP结构,就是key=>val 结构的数据,和数组差不多,加1~4个字节表⽰后⾯有多少个项。
这个是官⽅的数据表⽰结构⽂档:
总的来说,MessagePack对数字、多字节字符、数组等都做了很多优化,减少了⽆⽤的字符,⼆进制格式,也保证不⽤字符化带来额外的存储空间的增加,所以MessagePack⽐JSON⼩是肯定的,⼩多少,得看你的数据。如果你⽤来存英⽂字符串,那⼏乎是没有区别….
为啥会快?
先说说JSON怎么解析吧,我们开发中⼀般都⽤cJSON这个库,cJSON存储的时候是采⽤链表存储的,其访问⽅式很像⼀颗树。每⼀个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链
表;每个节点也可以有孩⼦节点,通过child指针来访问,进⼊下⼀层。问题就是⾸先,构造这个链表的时候,得⼀个字符⼀个字符地匹配过去吧,得判断是不是引号、括号之类的吧…
但是MessagePack 则简单多了,直接⼀遍遍历过去了,从前⾯的数据头,就可以知道后⾯的是什么数据,指针应该向后移动多少,⽐JSON的构建链表少了很多⽐较的过程。
适合高中生看的书
来计算个数据吧,把刚才的数组,encode、decode重复1000万次:
msgpack_unpack(msgpack_pack($arr));
json_decode(json_encode($arr));
Json:37.099s
MessagePack:22.050s
⼤概是快这么多吧,如果数组更⼤,理论上,MessagePack⽐Json快更多。
MessagePack的常⽤的地⽅:
MessagePack 不是给JS⽤的,虽然它有JS的库,但是⽤浏览器来解析MessagePack是⼀件很悲剧的
事情,我曾经测试过(如果我还能找
到,我会提供代码),在低端浏览器下,JS计算MessagePack会卡死在那⾥,毕竟JSON是javascript亲⽣的,⽤起来⾃然⽐
MessagePack要容易。
MessagePack主要⽤于结构化数据的缓存和存储:
1.存在Memcache中,因为它⽐json⼩,可以省下⼀些内存来,速度也⽐json快⼀些,页⾯速度⾃然快⼀个档次。当然,也有⼀种情况,我在mc中存json,然后直接出来就是页⾯可⽤的json,都不⽤解析json了(当然这个在实际开发中⽐较少见)。
2.存在可以持久化的Key-val存储中。
MessagePack 的现状:
我就说PHP吧,因为C、C++的没啥好说的,就是解包、打包,速度⽐JSON快⼀些,但是业务逻辑的数据太多,还是先考虑上层的吧。PHP的MessagePack的扩展的安装:
使⽤⽅法:
这个MessagePack的PHP扩展,是传说中的开发维护的,在鸟哥的中,也使⽤了MessagePack 作为打包协议之⼀。
从现状看来,MessagePack⽬前还很少有公司⼤规模使⽤?这是为什么呢?由于没有读过MessagePack的相关的源码,所以在这个范畴,鸟哥最有发⾔权…
后来,redis 2.6⽀持了MessagePack…
先写到这⾥了,有空了,再补充⼀些,⽐如MessagePack 和 protocol buffer的异同之类的,洗洗睡了 (1)
2
3
4
5
气候变暖的原因6 可以⽤PECL 的安装⽅式:pecl install msgpack 也可以编译源码安装:$/path/to/phpize $./configure $make && make install
1
2
3
4
5 <?php $data = array (0=>1,1=>2,2=>3);$msg = msgpack_pack($data );$data = msgpack_unpack($msg );
>