protobuffer的前世今生(三)——序列化和反序列化性能比较

时间:2022-07-25
本文章向大家介绍protobuffer的前世今生(三)——序列化和反序列化性能比较,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

性能对比

下面是一些网上的对比图片,以及两年前有人做过的代码测试结果。

性能测试

网上有个人,做了详细的测试。 因为proto更擅长于整数的编码和处理,所以结论如下: 如果你的生产环境中的JSON没有那么多的double字段,都是字符串占大头,那么基本上来说替换成 Protobuf 也就是仅仅比 Jsoniter 提高一点点,肯定在2倍之内。如果不幸的话,没准 Protobuf 还要更慢一点。

序列化 & 反序列化过程

序列化过程如下:

  1. 判断每个字段是否有设置值,有值才进行编码
  2. 根据 字段标识号&数据类型 将 字段值 通过不同的编码方式进行编码

由于:

  1. 编码方式简单(只需要简单的数学运算 = 位移等等)
  2. 采用 Protocol Buffer 自身的框架代码 和 编译器 共同完成 所以Protocol Buffer的序列化速度非常快。

反序列化过程如下:

  1. 调用 消息类的 parseFrom(input) 解析从输入流读入的二进制字节数据流

从上面可知,Protocol Buffer解析过程只需要通过简单的解码方式即可完成,无需复杂的词法语法分析,因此 解析速度非常快。

  1. 将解析出来的数据 按照指定的格式读取到 Java、C++、Phyton 对应的结构类型中

由于:

  1. 解码方式简单(只需要简单的数学运算 = 位移等等)
  2. 采用 Protocol Buffer 自身的框架代码 和 编译器 共同完成

所以Protocol Buffer的反序列化速度非常快。

对比于XML 的序列化 & 反序列化过程

XML的反序列化过程如下:

  1. 从文件中读取出字符串
  2. 将字符串转换为 XML 文档对象结构模型
  3. 从 XML 文档对象结构模型中读取指定节点的字符串
  4. 将该字符串转换成指定类型的变量

上述过程非常复杂,其中,将 XML 文件转换为文档对象结构模型的过程通常需要完成词法文法分析等大量消耗 CPU 的复杂计算。 因为序列化 & 反序列化过程简单,所以序列化 & 反序列化过程速度非常快,这也是 Protocol Buffer效率高的原因。

总结

Protocol Buffer的性能好,主要体现在 序列化后的数据体积小 & 序列化速度快,最终使得传输效率高,其原因如下:

序列化速度快的原因:

  1. 编码 / 解码 方式简单(只需要简单的数学运算 = 位移等等)
  2. 采用 Protocol Buffer 自身的框架代码 和 编译器 共同完成 序列化后的数据量体积小(即数据压缩效果好)的原因:
  3. Protocol Buffer 比 JSON 和 XML 少了 {、}、: 这些符号,体积也减少一些。再加上 varint 压缩,gzip 压缩以后体积更小!
  4. Protocol Buffer 是 Tag - Value (Tag - Length - Value)的编码方式的实现,减少了分隔符的使用,数据存储更加紧凑,如Varint、Zigzag编码方式等等

缺点:

  1. Protocol Buffer 不是自我描述的,离开了数据描述 .proto 文件,就无法理解二进制数据流。这点即是优点,使数据具有一定的“加密性”,也是缺点,数据可读性极差。所以 Protocol Buffer 非常适合内部服务之间 RPC 调用和传递数据