首页 > 编程知识 正文

序列化框架,msgpack使用

时间:2023-05-05 23:22:54 阅读:168859 作者:2493

效率:测试

msgpack,json,serialize

10000次包装

长50、62、87

需要9、9、9,95ms、17.45ms、8.85ms

解开包

需要14.76ms、23.93ms、14.61ms

什么是消息包? 首先来看看公式的说明:

messagepackisanefficientbinaryserializationformat.itletsyouexchangedataaamongmultiplelanguageslikejson.but it’sfasterandsterandsmater toasinglebyte,andtypicalshortstringsrequireonlyoneextrabyteinadditiontothestringsthemselves。

消息包是一种高效的二进制序列化格式。 允许像JSON一样在各种语言之间交换数据。 但是比JSON更快更小。 小整数编码为1字节,短字符串只需比其长度多1字节。

官方用一句话概括了这东方:

it’slike JSON。

快速和小型。

最初研究MessagePack大约是在两年前,他还就MessagePack是什么样的,在什么场合使用,它是用于Javascript等问题进行了讲解。 但是两年过去了,博客平台的旧系统太多了,这个合同一直没能推广使用。 随后,redis宣布支持消息包格式和pintrest等公司,并积极使用该协议进行开发。 说明这种格式确实有很多先进性。

消息包、协议缓冲器和json的速度比较

这张图片是以前的MessagePack官网的首页图片,数字对比确实很好地反映了问题。 笔者不太了解协议缓冲区,XML也太旧了,所以跳过他们俩,只讨论了JSON和消息包。

为什么很小?

首先,让我解释一下消息包为什么小于JSON。 首先介绍json:

{“name“:”heyue“,”sex“:” u 7537“,”company“:”Sina“,”age“:30}

这个json的长度是57字节,但是为了表示这个数据结构,使用了23字节。 这大括号、引号、冒号等会白白地出现很多。 让我们在http://json.org/中查看json的数据标签定义。

换成消息包,我只能给大家贴代码和结果。 38字节:

? php

$arr

=array('name'='heyue ',' sex'='男人',' company'='sina ',' age'=30 );

echo

' JSON : '.strlen (JSON _ encode ($ arr ) ).'n );

echo

'消息包: '.strlen (msg pack _ pack ($ arr ) ).'n ';

$str

='mmdhf新浪';

echo

Jon_encode($str ).'n ';

echo

' JSON _ str : '.strlen (JSON _ encode ($ str ) ).'n ';

echo

' message pack _ str : '.strlen (msg pack _ pack ($ str ) ).'n ';

$str

='sina

china ';

echo

Jon_encode($str ).'n ';

echo

' JSON _ str : '.strlen (JSON _ encode ($ str ) ).'n ';

echo

' message pack _ str : '.strlen (msg pack _ pack ($ str ) ).'n ';

Json:57

消息包:38

//从这里可以看到消息包比json少得多

() (f55 ) ) 8DC3 ) u65b0) u6d6a )。

json_str:26

MessagePack_str:13

在UTF-8多字节字符中,消息包采用原生存储,4个汉字只使用13个字节,比原件多1个字节

' sina

china '

json_str:12

MessagePack_str:11

//英语文字是? 这只是比json少了一个引号的大小。

我不能给大家计算比率。 这是因为我们必须看到消息包的压缩算法,消息包的核心压力。

缩方式:

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的扩展的安装:


可以用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…
--------------------- 
作者:senlin1202 
来源:CSDN 
原文:https://blog.csdn.net/senlin1202/article/details/50800419 
版权声明:本文为博主原创文章,转载请附上博文链接!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。