protobuffer的前世今生(三)——序列化和反序列化性能比较
时间:2022-07-25
本文章向大家介绍protobuffer的前世今生(三)——序列化和反序列化性能比较,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
性能对比
下面是一些网上的对比图片,以及两年前有人做过的代码测试结果。
性能测试
网上有个人,做了详细的测试。 因为proto更擅长于整数的编码和处理,所以结论如下: 如果你的生产环境中的JSON没有那么多的double字段,都是字符串占大头,那么基本上来说替换成 Protobuf 也就是仅仅比 Jsoniter 提高一点点,肯定在2倍之内。如果不幸的话,没准 Protobuf 还要更慢一点。
序列化 & 反序列化过程
序列化过程如下:
- 判断每个字段是否有设置值,有值才进行编码
- 根据 字段标识号&数据类型 将 字段值 通过不同的编码方式进行编码
由于:
- 编码方式简单(只需要简单的数学运算 = 位移等等)
- 采用
Protocol Buffer
自身的框架代码 和 编译器 共同完成 所以Protocol Buffer
的序列化速度非常快。
反序列化过程如下:
- 调用 消息类的
parseFrom(input)
解析从输入流读入的二进制字节数据流
从上面可知,Protocol Buffer解析过程只需要通过简单的解码方式即可完成,无需复杂的词法语法分析,因此 解析速度非常快。
- 将解析出来的数据 按照指定的格式读取到 Java、C++、Phyton 对应的结构类型中
由于:
- 解码方式简单(只需要简单的数学运算 = 位移等等)
- 采用 Protocol Buffer 自身的框架代码 和 编译器 共同完成
所以Protocol Buffer的反序列化速度非常快。
对比于XML 的序列化 & 反序列化过程
XML的反序列化过程如下:
- 从文件中读取出字符串
- 将字符串转换为 XML 文档对象结构模型
- 从 XML 文档对象结构模型中读取指定节点的字符串
- 将该字符串转换成指定类型的变量
上述过程非常复杂,其中,将 XML 文件转换为文档对象结构模型的过程通常需要完成词法文法分析等大量消耗 CPU 的复杂计算。 因为序列化 & 反序列化过程简单,所以序列化 & 反序列化过程速度非常快,这也是 Protocol Buffer效率高的原因。
总结
Protocol Buffer的性能好,主要体现在 序列化后的数据体积小 & 序列化速度快,最终使得传输效率高,其原因如下:
序列化速度快的原因:
- 编码 / 解码 方式简单(只需要简单的数学运算 = 位移等等)
- 采用 Protocol Buffer 自身的框架代码 和 编译器 共同完成 序列化后的数据量体积小(即数据压缩效果好)的原因:
- Protocol Buffer 比 JSON 和 XML 少了 {、}、: 这些符号,体积也减少一些。再加上 varint 压缩,gzip 压缩以后体积更小!
- Protocol Buffer 是 Tag - Value (Tag - Length - Value)的编码方式的实现,减少了分隔符的使用,数据存储更加紧凑,如Varint、Zigzag编码方式等等
缺点:
- Protocol Buffer 不是自我描述的,离开了数据描述 .proto 文件,就无法理解二进制数据流。这点即是优点,使数据具有一定的“加密性”,也是缺点,数据可读性极差。所以 Protocol Buffer 非常适合内部服务之间 RPC 调用和传递数据
- LLDP在ODL中的实现及源码分析(一)
- 在虚拟机间NFV应用上使用采用DPDK的Open vSwitch
- ONOS集群选举分析
- OpenStack Spice协议配置
- 源码解读ODL的MAC地址学习(二)
- SpringBoot开发案例之整合Spring-data-jpa进阶篇
- SpringBoot开发案例之微信小程序录音上传
- SpringBoot开发案例之微信小程序文件上传
- SpringBoot开发案例之配置静态资源文件路径
- 源码解读ODL的MAC地址学习(一)
- SpringBoot开发案例之配置Druid数据库连接池
- SpringBoot开发案例之mail中文附件乱码
- SpringBoot开发案例之整合Swagger篇
- SpringBoot开发案例之整合mail队列进阶篇
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel5.6框架操作数据curd写法(查询构建器)实例分析
- PHP基于timestamp和nonce实现的防止重放攻击方案分析
- 怎么在 Linux 中查找一个命令或进程的执行时间
- laravel5.6 框架邮件队列database驱动简单demo示例
- php layui实现前端多图上传实例
- 解决Centos7下crontab+shell脚本定期自动删除文件问题
- PHP使用ajax的post方式下载excel文件简单示例
- laravel邮件发送的实现代码示例
- php curl发送请求实例方法
- ubuntn备份办法总结(四种)
- PHP中散列密码的安全性分析
- php的RSA加密解密算法原理与用法分析
- PHP实现微信提现(企业付款到零钱)
- centos7下rsync+crontab定期同步备份
- php抽象类和接口知识点整理总结