服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

[新文导读] Protobuf到底比JSON快几倍?全方位实测!

日期: 来源:即时通讯网收集编辑:InfoQ陶文

一、引言

本系列的前几篇主要是从各个角度讲解Protobuf的基本概念、技术原理这些内容,但回过头来看,对比JSON这种事实上的数据协议工业标准,Protobuf到底性能到底高多少?

本篇将以Protobuf为基准,对比市面上的一些主流的JSON解析库,通过全方位测试来证明给你看看Protobuf到底比JSON快几倍。

二、本文目录

1)前言
2)系列文章
3)写在前面
4)本次评测对象
5)整数解码性能测试(Decode Integer)
6)整数编码性能测试(Encode Integer)
7)双精度浮点数解码性能测试(Decode Double)
8)双精度浮点数编码性能测试(Encode Double)
9)对象解码性能测试(Decode Object)
10)对象编码性能测试(Encode Object)
11)整形列表解码性能测试(Decode Integer List)
12)整形列表编码性能测试(Encode Integer List)
13)对象列表解码性能测试(Decode Object List)
14)对象列表编码性能测试(Encode Object List)
15)双精度浮点数数组解码性能测试(Decode Double Array)
16)双精度浮点数数组编码性能测试(Encode Double Array)
17)字符串解码性能测试(Decode String)
18)字符串编码性能测试(Encode String)
19)本文总结
20)参考资料

三、系列文章

本文是系列文章中的第 篇,本系列总目录如下:

四、写在前面

拿 JSON 衬托 Protobuf 的文章真的太多了,经常可以看到文章中写道:“快来用 Protobuf 吧,JSON 太慢啦”。

但是 Protobuf 真的有吹的那么牛么?

我觉得从 JSON 切换到 Protobuf 怎么也得快一倍吧,要不然对不起付出的切换成本。然而,DSL-JSON 的家伙们居然说在Java语言里 JSON 和那些二进制的编解码格式有得一拼,这太让人惊讶了!

虽然你可能会说,咱们能不用苹果和梨来做比较了么?两个东西根本用途完全不一样好么。咱们用 Protobuf 是冲着跨语言无歧义的 IDL 的去的,才不仅仅是因为性能呢。好吧,这个我同意。但是仍然有那么多人盲目相信,Protobuf 一定会快很多,我觉得还是有必要彻底终结一下这个关于速度的传说。

DSL-JSON 的博客里只给了他们的测试结论,但是没有给出任何原因,以及优化的细节,这很难让人信服数据是真实的。你要说 JSON 比二进制格式更快,真的是很反直觉的事情。

稍微琢磨一下这个问题,就可以列出好几个 Protobuf 应该更快的理由。

比如:

  • 1)更容容易绑定值到对象的字段上。JSON 的字段是用字符串指定的,相比之下字符串比对应该比基于数字的字段tag更耗时;

  • 2)JSON 是文本的格式,整数和浮点数应该更占空间而且更费时;

  • 3)Protobuf 在正文前有一个大小或者长度的标记,而 JSON 必须全文扫描无法跳过不需要的字段。


但是仅凭这几点是不是就可以盖棺定论了呢?未必。

也有相反的观点:

  • 1)如果字段大部分是字符串,占到决定性因素的因素可能是字符串拷贝的速度,而不是解析的速度。在这个评测中,我们看到不少库的性能是非常接近的。这是因为测试数据中大部分是由字符串构成的;

  • 2)影响解析速度的决定性因素是分支的数量。因为分支的存在,解析仍然是一个本质上串行的过程。虽然Protobuf里没有[] 或者 {},但是仍然有类似的分支代码的存在。如果没有这些分支的存在,解析不过就是一个 memcpy 的操作而已。只有 Parabix 这样的技术才有革命性的意义,而 Protobuf 相比 JSON 只是改良而非革命;

  • 3)也许 Protobuf 是一个理论上更快的格式,但是实现它的库并不一定就更快。这取决于优化做得好不好,如果有不必要的内存分配或者重复读取,实际的速度未必就快。


有多个 benchmark 都把 DSL-JSON列到前三名里,有时甚至比其他的二进制编码更快。

经过我仔细分析,原因出在了这些 benchmark 对于测试数据的构成选择上。

因为构造测试数据很麻烦,所以一般评测只会对相同的测试数据,去测不同的库的实现。

这样就使得结果是严重倾向于某种类型输入的。

比如 https://github.com/eishay/jvm-serializers/wiki 选择的测试数据的结构是这样的:

01020304050607080910111213141516171819202122232425262728293031323334message Image {  required string uri = 1;      //url to the thumbnail  optional string title = 2;    //used in the html ALT  required int32 width = 3;     // of the image  required int32 height = 4;    // of the image  enum Size {    SMALL = 0;    LARGE = 1;  }  required Size size = 5;       // of the image (in relative terms, provided by cnbc for example)} message Media {  required string uri = 1;      //uri to the video, may not be an actual URL  optional string title = 2;    //used in the html ALT  required int32 width = 3;     // of the video  required int32 height = 4;    // of the video  required string format = 5;   //avi, jpg, youtube, cnbc, audio/mpeg formats ...  required int64 duration = 6//time in miliseconds  required int64 size = 7;      //file size  optional int32 bitrate = 8;   //video  repeated string person = 9;   //name of a person featured in the video  enum Player {    JAVA = 0;    FLASH = 1;  }  required Player player = 10;   //in case of a player specific media  optional string copyright = 11;//media copyright} message MediaContent {  repeated Image image = 1;  required Media media = 2;}


无论怎么去构造 small/medium/large 的输入,benchmark 仍然是存在特定倾向性的。

而且这种倾向性是不明确的。比如 medium 的输入,到底说明了什么?medium 对于不同的人来说,可能意味着完全不同的东西。

所以,在这里我想改变一下游戏的规则。不去选择一个所谓的最现实的配比,而是构造一些极端的情况。

这样,我们可以一目了然的知道,JSON的强项和弱点都是什么。通过把这些缺陷放大出来,我们也就可以对最坏的情况有一个清晰的预期。具体在你的场景下性能差距是怎样的一个区间内,也可以大概预估出来。

五、本次评对象

好了,废话不多说了,JMH 撸起来。

benchmark 的对象有以下几个:

  • 1)Jackson:Java 程序里用的最多的 JSON 解析器。benchmark 中开启了 AfterBurner 的加速特性;

  • 2)DSL-JSON:世界上最快的 Java JSON 实现;

  • 3)Jsoniter:抄袭 DSL-JSON 写的实现;

  • 4)Fastjson:在中国很流行的 JSON 解析器;

  • 5)Protobuf:在 RPC (远程方法调用)里非常流行的二进制编解码格式;

  • 6)Thrift:另外一个很流行的 RPC 编解码格式。这里 benchmark 的是 TCompactProtocol。

六、参考资料

[1] Protobuf从入门到精通,一篇就够!

http://www.52im.net/thread-4080-1-1.html

[2] 如何选择即时通讯应用的数据传输格式

http://www.52im.net/thread-276-1-1.html

[3] 强列建议将Protobuf作为你的即时通讯应用数据传输格式

http://www.52im.net/thread-277-1-1.html

[4] APP与后台通信数据格式的演进:从文本协议到二进制协议

http://www.52im.net/thread-1536-1-1.html

[5] 面试必考,史上最通俗大小端字节序详解

http://www.52im.net/thread-3101-1-1.html

[6] 移动端IM开发需要面对的技术问题(含通信协议选择)

http://www.52im.net/thread-133-1-1.html

[7] 简述移动端IM开发的那些坑:架构设计、通信协议和客户端

http://www.52im.net/thread-289-1-1.html

[8] 理论联系实际:一套典型的IM通信协议设计详解

http://www.52im.net/thread-283-1-1.html

[9] 58到家实时消息系统的协议设计等技术实践分享

http://www.52im.net/thread-298-1-1.html


七、全文链接

即时通讯网(52im.net)社区链接:http://www.52im.net/thread-4095-1-1.html,或点击下文的“阅读原文”!



相关阅读

  • 关于性能测试需要知道的

  • 随着各企业的业务发展、用户量以及数据量的不断增加,系统承载的压力也会随之增加,服务系统的性能好坏又严重影响企业的利益。因此,性能测试重要性与需求越来越强烈。常见的性能
  • 欢迎订阅2023年《文化纵横》杂志

  • 尊敬的读者朋友:当前,世界百年未有之大变局进入加速演变期,形势正发生重大变化,国际环境日趋错综复杂。在变局的风险和不确定性中,各种异化、内卷、焦虑呈现叠加之势。对于中国
  • 『案例』2022数字营销高峰论坛活动策划方案

  • 4A营销广告圈,让策划变简单!『4A营销广告圈』做事的不如写PPT的!为什么你写的方案又慢又总通不过?其实,那可能是因为,你没有一个营销方案库!今天道叔要为小伙伴们带来『4A营销广告
  • 『案例』母婴用品品牌怎么构建品牌战略生态?

  • 4A营销广告圈,让策划变简单!『4A营销广告圈』做事的不如写PPT的!为什么你写的方案又慢又总通不过?其实,那可能是因为,你没有一个营销方案库!今天道叔要为小伙伴们带来『4A营销广告

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 基建对金融数据的支撑越来越强

  • 文 | 红塔证券 李奇霖 杨欣联系方式 | yaxi_yx_2022年8月末社会融资规模存量为337.21万亿元,同比增长10.5%,增速较上月下滑0.2个百分点。当月增量为2.43万亿元,比上年同期少557
  • 如何看待8月经济数据

  • 文 | 红塔证券 杨欣 李奇霖联系方式 | yaxi_yx_今天公布了经济数据:社会消费品零售总额当月同比增为5.4%,前值2.7%;规模以上工业增加值当月同比增长4.2%,前值3.8%;固定资产投资(不
  • 超预期的PMI

  • 文 | 红塔证券 杨欣 李奇霖联系方式 | yaxi_yx_9月份,制造业采购经理指数(PMI)为50.1%,比上月上升0.7个百分点,升至扩张区间。非制造业商务活动指数为50.6%,比上月下降2.0个百分点