新型序列化类库MessagePack,比JSON更快、更小的格式
MessagePack is an efficient binary serialization 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 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 官方网站的首页图片,数字对比确实很能反映问题,笔者不是很了解protocol buffers,XML又太老土了,就跳过他们俩了,只讨论JSON和MessagePack了。 为啥会小?
先大概说下MessagePack 为啥会比JSON小吧,先来段json: {“name“:”heyue“,”sex“:”\u7537“,”company“:”sina“,”age“:30} 这个json长度为57字节,但是为了表示这个数据结构(所有标红色的地方就是他为了表示这个数据结构而不得不添加的),它用了23个字节(就是那些大括号、引号、冒号之类的,他们是白白多出来的)。大家可以去http://json.org/ 上看看json的数据标示定义。 换成MessagePack,我只能给大家贴代码和结果了,38字节: ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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 表示这后面,是个uint 8,用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的扩展的安装: ?
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);
?>
这个MessagePack的PHP扩展,是传说中的鸟哥Laruence开发维护的,在鸟哥的Yar中,也使用了MessagePack 作为打包协议之一。 从现状看来,MessagePack目前还很少有公司大规模使用?这是为什么呢?由于没有读过MessagePack的相关的源码,所以在这个范畴,鸟哥最有发言权… 后来,redis 2.6支持了MessagePack… 先写到这里了,有空了,再补充一些,比如MessagePack 和 protocol buffer的异同之类的,洗洗睡了…
新型序列化类库MessagePack,比JSON更快、更小的格式的更多相关文章
- Mockplus更快更简单的原型设计
更快更简单的原型设计 https://www.mockplus.cn/ Mockplus,更快更简单的原型设计工具.快速创建原型,一键拖拽创建交互,团队协作省事省力.微软.华为.东软.育碧.Oracl ...
- Microsoft Hyperlapse——让第一人称视频更快更流畅
Hyperlapse--让第一人称视频更快更流畅" title="Microsoft Hyperlapse--让第一人称视频更快更流畅"> 职业摄影师Nick Di ...
- Swift 4.0 正式发布,更快更兼容更好用
Swift4现已正式发布!Swift4在Swift3的基础上,提供了更强大的稳健性和稳定性,为Swift3提供源码兼容性,对标准库进行改进,并添加了归档和序列化等功能. 你可以通过观看WWDC2017 ...
- 安装好Windows 8后必做的几件事情,让你的Win8跑的更快更流畅。
1.关闭家庭组,因为这功能会导致硬盘和CPU处于高负荷状态. 关闭方法:Win+C-设置-更改电脑设置-家庭组-离开 如果用不到家庭组可以直接把家庭组服务也给关闭了:控制面板-管理工具-服务-Home ...
- 正则表达式匹配可以更快更简单 (but is slow in Java, Perl, PHP, Python, Ruby, ...)
source: https://swtch.com/~rsc/regexp/regexp1.html translated by trav, travmymail@gmail.com 引言 下图是两种 ...
- CPNDet:粗暴地给CenterNet加入two-stage精调,更快更强 | ECCV 2020
本文为CenterNet作者发表的,论文提出anchor-free/two-stage目标检测算法CPN,使用关键点提取候选框再使用两阶段分类器进行预测.论文整体思路很简单,但CPN的准确率和推理速度 ...
- 不妨试试更快更小更灵活Java开发框架Solon
@ 目录 概述 定义 性能 架构 实战 Solon Web示例 Solon Mybatis-Plus示例 Solon WebSocket示例 Solon Remoting RPC示例 Solon Cl ...
- 更好更快更高效解析JSON说明
现在来一个实例解析类,直接就把解析JSON到QVariant去了.唯一不足的是没有搞错误处理,具体方法也请各位自行参考json-c的发行文档,这样比较方便叙述,STL或者Boost我都没有认真接触过, ...
- js 性能基准测试工具-告别可能、也许、大概这样更快更省
平时写js经常遇到这样做是不是更快点?但又没有具体简单可测试的工具,最近也倒序看博客园司徒正美 js分类下的文章 [ps:去年灵光一闪,发现看博客园排名前100的博客.按照文章分类倒序看是学习最快的方 ...
随机推荐
- jquery左边滚动,完毕后跳转回来
代码如下 function in_scroll(){ $liW = ; $num = $(".in-cy li").size(); $ulW = $liW*$num; $(&quo ...
- js与php转换时间戳
php时间:1368524732 js代码: function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleStri ...
- oracle安装常见问题
版本信息:CentOS6.5 + oracle11G 1.监视器颜色错误: [oracle@bogon database]$ 正在启动 Oracle Universal Installer... 检查 ...
- sufeinet
http://www.sufeinet.com http://tool.sufeinet.com/
- 年轻人,你活着不是为了观察K线做布朗运动
谈股票市场的赚钱陷阱 年轻人,你活着不是为了观察K线做布朗运动 作者:李晓鹏(2015-01-10) 这篇文章本来是该两年前写的,奉劝大家不要去玩股票.因为那个时候我的<中国崛起的经济学分析&g ...
- Python开发【第五篇】:Python基础之杂货铺
字符串格式化 Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-310 ...
- 修改hosts
- 浅谈T-SQL中的子查询
引言 这篇文章我们来简单的谈一下子查询的相关知识.子查询可以分为独立子查询和相关子查询.独立子查询不依赖于它所属的外部查询,而相关子查询则依赖于它所属的外部查询.子查询返回的值可以是标量(单值).多值 ...
- <Web 之困 现代Web应用安全指南>一本好书 69.00?
NET代码安全 界面漏洞防范与程序优化 一. SQL 注入攻击的源头 1. 过滤或转移危险字符 2. 使用SqlParameter类:.NET 框架有一个叫做SqlParameter 的集合类型,可 ...
- ServletContext中常用方法
..获取Tomcat的Context的初始化参数. 1.获取Tomcat的server.xml中设置Context的初始化参数. 例如: <Context path="/testcon ...