msgpack---序列化

来源:互联网 发布:java 字符串替换 编辑:程序博客网 时间:2024/06/18 07:53

效率:测试

msgpack,json,serialize

打包10000次

长度50,62,87

耗时9,95ms,17.45ms,8.85ms

解包

耗时14.76ms,23.93ms,14.61ms

 

MessagePack 是个什么东东?先来看一段官方的解释:

MessagePack is an efficient binary serialization format. It letsyou exchange data among multiple languages like JSON. But it’sfaster and smaller. Small integers are encoded into a single byte,and typical short strings require only one extra byte in additionto the strings themselves.

MessagePack 是一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小。小的整数会被编码成一个字节,短的字符串仅仅只需要比它的长度多一字节的大小。

官方用一句话总结了这个东东:

It’s like JSON.
but fast and small.

最初研究MessagePack大概是两年前了,还开了个讲座给大家讲MessagePack是个什么东西,大概用在什么场合,它是不是给Javascript用的之类的。但是两年过去了,由于博客平台老系统太多,以至于这个协议一直没有能推进使用。后来,redis宣布支持MessagePack格式,以及pintrest等公司,也在积极得使用这个协议进行开发,说明这个格式确实有很多先进性。

MessagePack、protocol buffers、json的速度对比

MessagePack、protocol buffers、json的速度对比

这张图片是以前MessagePack 官方网站的首页图片,数字对比确实很能反映问题,笔者不是很了解protocolbuffers,XML又太老土了,就跳过他们俩了,只讨论JSON和MessagePack了。

为啥会小?

先大概说下MessagePack 为啥会比JSON小吧,先来段json:

{“name“:”heyue“,”sex“:”\u7537“,”company“:”sina“,”age“:30} 

这个json长度为57字节,但是为了表示这个数据结构(所有标红色的地方就是他为了表示这个数据结构而不得不添加的),它用了23个字节(就是那些大括号、引号、冒号之类的,他们是白白多出来的)。大家可以去http://json.org/ 上看看json的数据标示定义。

换成MessagePack,我只能给大家贴代码和结果了,38字节:

\<\?php
$arr
=array('name'=>"heyue",'sex'=>'男','company'=>'sina','age'=>30);
echo
"Json:".strlen(json_encode($arr))."\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";
 
\?\>
 
Json:57
Messagepack:38
//从这里可以看出MessagePack比json少了好多
"\u4f55\u8dc3\u65b0\u6d6a"
json_str:26
MessagePack_str:13
//在UTF-8多字节字符中,MessagePack采用原生态存储,4个汉字,只用了13字节,比原始的只多了1字节
"sina
 china"
json_str:12
MessagePack_str:11
//英文字符呢?这个仅仅是比json少了一个引号的大小。
我不能给大家算比例,因为这个得看MessagePack的压缩算法,MessagePack的核心压缩方式:

1.true、false 之类的:这些太简单了,直接给1个字节,(0xc2 表示true,0xc3表示false)

2.不用表示长度的:就是数字之类的,他们天然是定长的,是用一个字节表示后面的内容是什么东东,比如用(0xcc 表示这后面,是个uint8,用oxcd表示后面是个uint 16,用 0xca 表示后面的是个float 32).

3.不定长的:比如字符串、数组,类型后面加1~4个字节,用来存字符串的长度,如果是字符串长度是256以内的,只需要1个字节,MessagePack能存的最长的字符串,是(2^32-1 ) 最长的4G的字符串大小。

4.ext结构:表示特定的小单元数据。

5.高级结构:MAP结构,就是key=>val 结构的数据,和数组差不多,加1~4个字节表示后面有多少个项。

这个是官方的数据表示结构文档:https://gist.github.com/frsyuki/5432559

总的来说,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的扩展的安装:


可以用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);
\?\>
这个MessagePack的PHP扩展,是传说中的鸟哥Laruence开发维护的,在鸟哥的Yar中,也使用了MessagePack作为打包协议之一。

从现状看来,MessagePack目前还很少有公司大规模使用?这是为什么呢?由于没有读过MessagePack的相关的源码,所以在这个范畴,鸟哥最有发言权…

后来,redis 2.6支持了MessagePack…

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 上海居住证没下来换住址了怎么办 工商注册后大股东不注资怎么办 公司不给去办理变更股东信息怎么办 滴滴车主注册没有自己的车型怎么办 代办用虚假地址注册的公司怎么办? 写字楼注册公司租户不租了怎么办 租户没把公司迁出我该怎么办 租户不肯把户口迁出了业主怎么办 同片区个体户营业场所搬迁怎么办 个体领发票的本丢了怎么办 领房产证发票和合同丢了怎么办 税务登记证5年没有办怎么办 二证合一后税务登记证怎么办? 微信漂流瓶打招呼对方收不到怎么办 添加不上徽信好友的微信帐号怎么办 手机号码不用了微信密码忘了怎么办 别人用我的手机号码注册微信怎么办 电脑此网站的安全证书有问题怎么办 起诉离婚开庭时被告不到场怎么办 商标35类被别人注册了怎么办 商标被注销后被别人注册怎么办 电商35类商标被抢注怎么办 血小板太低怎么办可以吃水果吗? 微信好友删除了只记得昵称怎么办 优酷会员1080p很卡怎么办 电脑最下面的任务栏不显示怎么办 ea账号保留的问题忘了怎么办 微博超级话题账号被屏蔽怎么办 梦幻西游手机将军令号码换了怎么办 文档的内容被锁定无法修改怎么办 用户没有权限访问u盘时该怎么办? 电脑找不到ip地址连不上网怎么办 商标提前被别人注册微博昵称怎么办 扫码注册显示手机号被占用怎么办 vivo手机屏锁密码忘了怎么办 手机号注册微博手机号不用了怎么办 微博更换手机号被别人注册过怎么办 怎么有个qq注册验证码怎么办 12306手机丢了密码忘了怎么办 教师考试注册时邮箱填写错误怎么办 计算机二级注册时邮箱填错了怎么办