最近弄 Redis ,涉及数据序列化存储的问题,对比了:JSON, Serialize, Msgpack, Hprose 四种方式

1. 对序列化后的字符串长度对比:

测试代码:

$arr = [0, 1, 2, 'a', 'b', 'c', 'd', 'a'=>'12', '包含中文', 'abcd包含中文efg'=>'abc一二三四defg', '键名'=>['abc'=>['def'=>123, 456, 'abcd中文内容efg'], 'a之间c'=>['a'=>123, 'c', 5=>6]]];
$str = hprose_serialize($arr);
echo 'Hprose: ';
echo '<br>';
echo '长度: '. strlen($str);
echo '<br>';
echo '内容:'. $str;
echo '<hr>';
$str = msgpack_pack($arr);
echo 'Msgpack: ';
echo '<br>';
echo '长度: '. strlen($str);
echo '<br>';
echo '内容:'. $str;
echo '<hr>';
$str = json_encode($arr);
echo 'JSON: ';
echo '<br>';
echo '长度: '. strlen($str);
echo '<br>';
echo '内容:'. $str;
echo '<hr>';
$str = serialize($arr);
echo 'Serialize: ';
echo '<br>';
echo '长度: '. strlen($str);
echo '<br>';
echo '内容:'. $str;
echo '<hr>';

结果:

Hprose:

长度: 196

内容:m11{0011223ua4ub5uc6uds1”a”s2”12”7s4”包含中文”s11”abcd包含中文efg”s11”abc一二三四defg”s2”键名”m2{s3”abc”m3{s3”def”i123;0i456;1s11”abcd中文内容efg”}s4”a之间c”m3{r1;i123;0uc56}}}


Msgpack:

长度: 139

内容:��a�b�c�d�a�12�包含中文�abcd包含中文efg�abc一二三四defg�键名��abc��def{���abcd中文内容efg�a之间c��a{�c


JSON:

长度: 281

内容:

{“0”:0,”1”:1,”2”:2,”3”:”a”,”4”:”b”,”5”:”c”,”6”:”d”,”a”:”12”,”7”:”\u5305\u542b\u4e2d\u6587”,”abcd\u5305\u542b\u4e2d\u6587efg”:”abc\u4e00\u4e8c\u4e09\u56dbdefg”,”\u952e\u540d”:{“abc”:{“def”:123,”0”:456,”1”:”abcd\u4e2d\u6587\u5185\u5bb9efg”},”a\u4e4b\u95f4c”:{“a”:123,”0”:”c”,”5”:6}}}


Serialize:

长度: 321

内容:a:11:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;s:1:”a”;i:4;s:1:”b”;i:5;s:1:”c”;i:6;s:1:”d”;s:1:”a”;s:2:”12”;i:7;s:12:”包含中文”;s:19:”abcd包含中文efg”;s:19:”abc一二三四defg”;s:6:”键名”;a:2:{s:3:”abc”;a:3:{s:3:”def”;i:123;i:0;i:456;i:1;s:19:”abcd中文内容efg”;}s:8:”a之间c”;a:3:{s:1:”a”;i:123;i:0;s:1:”c”;i:5;i:6;}}}


对比结论:

一般情况下,Msgpack < JSON < Serialize 。差距一般在 1~3倍左右,Msgpack 体积非常小

2. 序列化速度对比:

测试代码:

echo 'Begin ~~<br><hr><br>';
$begin = microtime(true);
$bm = memory_get_usage(); for ($i = 0; $i <= 100000; $i++) {
// $str = hprose_serialize($arr);
// $str = msgpack_pack($arr);
// $str = serialize($arr);
$str = json_encode($arr);
} $em = memory_get_usage(); echo 'End !<br><hr><br>Use Time :';
echo microtime(true) - $begin;
echo '<br><hr><br>Use Mem:';
echo ceil(($em - $bm)/1024/1024) .'MB';

测试结果:

Hprose 耗时: 0.435 ~ 0.466

Msgpack 耗时: 0.328 ~ 0.378

Serialize 耗时: 0.496 ~ 0.541

JSON 耗时: 0.431 ~ 0.469


3. 反序列化速度对比

测试代码:

echo 'Begin ~~<br><hr><br>';
$begin = microtime(true);
$bm = memory_get_usage(); //$str = hprose_serialize($arr);
//$str = msgpack_pack($arr);
//$str = serialize($arr);
$str = json_encode($arr);
for ($i = 0; $i <= 100000; $i++) {
// hprose_unserialize($str);
// msgpack_unpack($str);
// unserialize($str);
json_decode($str);
} $em = memory_get_usage(); echo 'End !<br><hr><br>Use Time :';
echo microtime(true) - $begin;
echo '<br><hr><br>Use Mem:';
echo ceil(($em - $bm)/1024/1024) .'MB';

测试结果:

Hprose 耗时: 0.553 ~ 0.591

Msgpack 耗时: 0.492 ~ 0.550

Serialize 耗时: 0.496 ~ 0.531

JSON 耗时: 0.852 ~ 0.893


4. Redis 测试:

每次测试清空后添加 两百万 条进队列,查看 Reids info 中 Memory 信息:

a. 初始化空数据时:

b. 使用 Msgpack 序列化后录入

c. 使用 JSON 编码后录入

d. 使用 Serialize 序列化后录入

对比结果:

Msgpack 占用内存 385M

JSON 占用内存 660M

Serialize 占用内存 752M

Hprose 我没测试,体积应该在 Msgpack 和 JSON 之间


总结:

速度: Msgpack 速度最快,其次 Serialize, JSON 反序列化速度慢了近一倍

体积: Msgpack 最小,其次 JSON,Serialize 体积最大,一般比 Msgpack 大 1~3 倍。

推荐使用 Msgpack 进行序列化

感觉从各方面来看 Msgpack 都是非常牛逼的,只不过需要自己单独安装 Msgpack 的扩展,不过安装也很简单的。

服务器上可以直接 pecl install msgpack

如果不行的话,就手动下载 tgz 包:

在这里下载最新版本 https://pecl.php.net/package/msgpack

然后 pecl install msgpack-0.5.6.tgz 即可

之前用 Hprose 时据说他的 PHP Pecl 扩展 hprose_serialize 比 Msgpack 还要快,但今天测试发现比 Msgpack 还要慢一点点,体积也要大一些,不过相对于 PHP 的 serialize 来还是要好一些吧。


测试平台说明:

windows7 x64

I7 4核8线程

内存16G

PHP5.5.19

Redis 2.8.21


Redis 数据序列化方法 serialize, msgpack, json, hprose 比较的更多相关文章

  1. form 转json,将form表单中的数据序列化数组后转换为Json

    页面中引用了jquery,第一想到的就是序列化,但是序列化后的表单字段为a=1&b=2这种. 这里写一个jquery的扩展方法 $.fn.serializeObject = function( ...

  2. C# 使用Json.NET对数据进行序列化和反序列化 | c# json serialize and deserialize using json.net JsonConvert

    本文首发于个人博客https://kezunlin.me/post/22391aa3/,欢迎阅读最新内容! c# json serialize and deserialize using json.n ...

  3. jQuery的序列化元素 serialize()方法 serializeArray()方法 param()方法

    当提交的表单元素较多时用serialize()方法,serialize()方法也是作用于一个jQuery的对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求. serialize() 方法通 ...

  4. Python基础4 迭代器,生成器,装饰器,Json和pickle 数据序列化

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  5. 迭代器/生成器/装饰器 /Json & pickle 数据序列化

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  6. JSON和php里的数据序列化

    JSON就是一种数据结构,独立于语言 {"1":"one","2":"two","3":" ...

  7. Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化

    一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...

  8. Python之数据序列化(json、pickle、shelve)

    本节内容 前言 json模块 pickle模块 shelve模块 总结 一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Py ...

  9. python基础6之迭代器&生成器、json&pickle数据序列化

    内容概要: 一.生成器 二.迭代器 三.json&pickle数据序列化 一.生成器generator 在学习生成器之前我们先了解下列表生成式,现在生产一个这样的列表[0,2,4,6,8,10 ...

随机推荐

  1. 1572: [Usaco2009 Open]工作安排Job[贪心]

    Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有1000000000个单 ...

  2. c语言算法题目求职用

    1.栈的压入与压出/* 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.n<=100000 用一个栈作辅助,顺序描述压入序列和弹出序列,如果当前位置上压入序列 ...

  3. Nginx+phpfastcgi下flush输出问题

    最近由于业务需要,需要使用php的flush输出缓存刷新,处理浏览器超时问题. 最初的测试代码如下: ob_start();//打开缓冲区 for ($i=10; $i>0; $i--) { e ...

  4. DedeCms密码解密[转]

    dede 的密码怎么破解,dede后台.32位的DEDE密码如何破解 dede 的密码是32位MD5减去头5位,减去尾七位,得到20 MD5密码,方法是,前减3后减1,得到16位MD5. 比如我的数据 ...

  5. IOS学习之路二十二(UIAlertView获得文本框内容及添加北京图片)

    今天写项目要用到警告框带输入框的,于是就自己做了个小demo. 效果图大体如下: 下面简单介绍一下UIAlertView alertViewStyle属性有以下三种选项:  UIAlertViewSt ...

  6. Jquery文本框值改变事件(支持火狐、ie)

    Jquery值改变事件支持火狐和ie浏览器,并且测试通过,绑定后台代码可以做成autocomplete控件. 具体代码列举如下: $(document).ready(function () { $(& ...

  7. Define Constraints That Are Minimal and Sufficient 设定不多不少的约束

    Define Constraints That Are Minimal and Sufficient 设定不多不少的约束   今天第二章第二节. 主管不在,然后暂时没什么任务,把第二节看了,然后整理一 ...

  8. MySQL 常用命令大全

    Mysql常用命令行大全 第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密码 键 ...

  9. WCF小实例以及三种宿主

    WCF小实例以及三种宿主 最近一直在学习WCF相关知识,下面将通过一个小实例对所学的知识进行简单的回顾:本实例是一个简单三层操作数据库,并且也简单实现的三种宿主(控制台宿主,IIS宿主以及Window ...

  10. 深入浅出MyBatis-Sqlsession

    前面的章节主要讲mybatis如何解析配置文件,这些都是一次性的过程.从本章开始讲解动态的过程,它们跟应用程序对mybatis的调用密切相关.本章先从sqlsession开始. 创建 正如其名,Sql ...