1.概述

转载:序列化:ProtoBuf 与 JSON 的比较!

介绍

ProtoBuf 是google团队开发的用于高效存储和读取结构化数据的工具。什么是结构化数据呢,正如字面上表达的,就是带有一定结构的数据。比如电话簿上有很多记录数据,每条记录包含姓名、ID、邮件、电话等,这种结构重复出现。

XML、JSON 也可以用来存储此类结构化数据,但是使用ProtoBuf表示的数据能更加高效,并且将数据压缩得更小。

原理

ProtoBuf 是通过ProtoBuf编译器将与编程语言无关的特有的.proto后缀的数据结构文件编译成各个编程语言(Java,C/C++,Python)专用的类文件,然后通过Google提供的各个编程语言的支持库lib即可调用API。(关于proto结构体怎么编写,可自行查阅文档)

ProtoBuf编译器安装

Mac: brew install protobuf

ProtoBuf使用案例

先创建一个proto文件

message.protosyntax = "proto3";message Person {int32 id = 1;string name = 2;repeated Phone phone = 4;enum PhoneType {MOBILE = 0;HOME = 1;WORK = 2;}message Phone {string number = 1;PhoneType type = 2;}
}

创建一个Java项目

并且将proto文件放置src/main/proto文件夹下

编译proto文件至Java版本
用命令行 cd 到src/main目录下

终端执行命令: protoc --java_out=./java ./proto/*.proto

会发现,在src/main/java里已经生成里对应的Java类

依赖Java版本的ProtoBuf支持库
这里只举一个用Gradle使用依赖的栗子

implementation 'com.google.protobuf:protobuf-java:3.9.1'

将Java对象转为ProtoBuf数据

Message.Person.Phone.Builder phoneBuilder = Message.Person.Phone.newBuilder();
Message.Person.Phone phone1 = phoneBuilder.setNumber("100860").setType(Message.Person.PhoneType.HOME).build();
Message.Person.Phone phone2 = phoneBuilder.setNumber("100100").setType(Message.Person.PhoneType.MOBILE).build();
Message.Person.Builder personBuilder = Message.Person.newBuilder();
personBuilder.setId(1994);
personBuilder.setName("XIAOLEI");
personBuilder.addPhone(phone1);
personBuilder.addPhone(phone2);Message.Person person = personBuilder.build();
long old = System.currentTimeMillis();
byte[] buff = person.toByteArray();
System.out.println("ProtoBuf 编码耗时:" + (System.currentTimeMillis() - old));
System.out.println(Arrays.toString(buff));
System.out.println("ProtoBuf 数据长度:" + buff.length);
将ProtoBuf数据,转换回Java对象
System.out.println("-开始解码-");
old = System.currentTimeMillis();
Message.Person personOut = Message.Person.parseFrom(buff);
System.out.println("ProtoBuf 解码耗时:" + (System.currentTimeMillis() - old));
System.out.printf("Id:%d, Name:%s\n", personOut.getId(), personOut.getName());
List<Message.Person.Phone> phoneList = personOut.getPhoneList();
for (Message.Person.Phone phone : phoneList) {System.out.printf("手机号:%s (%s)\n", phone.getNumber(), phone.getType());
}

比较

为了能体现ProtoBuf的优势,我写了同样结构体的Java类,并且将Java对象转换成JSON数据,来与ProtoBuf进行比较。JSON编译库使用Google提供的GSON库,JSON的部分代码就不贴出来了,直接展示结果

运行 1 次

【 JSON 开始编码 】
JSON 编码1次,耗时:22ms
JSON 数据长度:106
-开始解码-
JSON 解码1次,耗时:1ms【 ProtoBuf 开始编码 】
ProtoBuf 编码1次,耗时:32ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码1次,耗时:3ms

运行 10 次

【 JSON 开始编码 】
JSON 编码10次,耗时:22ms
JSON 数据长度:106
-开始解码-
JSON 解码10次,耗时:4ms【 ProtoBuf 开始编码 】
ProtoBuf 编码10次,耗时:29ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码10次,耗时:3ms

运行 100 次

【 JSON 开始编码 】
JSON 编码100次,耗时:32ms
JSON 数据长度:106
-开始解码-
JSON 解码100次,耗时:8ms【 ProtoBuf 开始编码 】
ProtoBuf 编码100次,耗时:31ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码100次,耗时:4ms

运行 1000 次

【 JSON 开始编码 】
JSON 编码1000次,耗时:39ms
JSON 数据长度:106
-开始解码-
JSON 解码1000次,耗时:21ms【 ProtoBuf 开始编码 】
ProtoBuf 编码1000次,耗时:37ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码1000次,耗时:8ms

运行 1万 次

【 JSON 开始编码 】
JSON 编码10000次,耗时:126ms
JSON 数据长度:106
-开始解码-
JSON 解码10000次,耗时:93ms【 ProtoBuf 开始编码 】
ProtoBuf 编码10000次,耗时:49ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码10000次,耗时:23ms

运行 10万 次

【 JSON 开始编码 】
JSON 编码100000次,耗时:248ms
JSON 数据长度:106
-开始解码-
JSON 解码100000次,耗时:180ms【 ProtoBuf 开始编码 】
ProtoBuf 编码100000次,耗时:51ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码100000次,耗时:58ms

总结

编解码性能
上述栗子只是简单的采样,实际上据我的实验发现

次数在1千以下,ProtoBuf的编码与解码性能,都与JSON不相上下,甚至还有比JSON差的趋势
次数在2千以上,ProtoBuf的编码解码性能,都比JSON高出很多
次数在10万以上,ProtoBuf的编解码性能就很明显了,远远高出JSON的性能

内存占用

ProtoBuf的内存34,而JSON到达106,ProtoBuf的内存占用只有JSON的1/3.

结尾

其实这次实验有很多可待优化的地方,就算是这种粗略的测试,也能看出来ProtoBuf的优势。

兼容

新增字段
在proto文件中新增 nickname 字段
生成Java文件
用老proto字节数组数据,转换成对象

Id:1992, Name:XIAOLEI
手机号:100860 (HOME)
手机号:100100 (MOBILE)
getNickname=

结果,是可以转换成功。

删除字段
在proto文件中删除 name 字段
生成Java文件
用老proto字节数组数据,转换成对象

Id:1992, Name:null
手机号:100860 (HOME)
手机号:100100 (MOBILE)
结果,是可以转换成功。

【java】序列化:ProtoBuf 与 JSON 的比较相关推荐

  1. Java 序列化对象为json字符串,属性首字母大写,并按照属性首字母排序

    1.创建类 import lombok.Data; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor;import c ...

  2. Java kryo/protobuf/protostuff序列化 or Json 性能对比

    Java kryo/protobuf/protostuff序列化 or Json 性能对比 - 腾飞的鹰 - 博客园 对于一个java object的序列化,想测一下使用json和使用一般序列化工具, ...

  3. 序列化:ProtoBuf与JSON的比较

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:https://my.oschina.net/xiaolei ...

  4. 序列化:Protobuf 与 JSON、XML 的对比

    Protobuf .JSON.XML 的对比 XML JSON PB 数据结构支持 复杂结构 简单结构 较复杂结构 数据保存方式 文本 文本 二进制 数据保存大小 大 一般 小 解析效率 慢 一般 快 ...

  5. Java序列化案例demo(包含Kryo、JDK原生、Protobuf、ProtoStuff以及hessian)

    文章目录 前言 一.Kryo序列化(优先选择) 介绍 快速开始 测试 二.JDK原生序列化 介绍 快速开始 测试 三.Protobuf序列化 介绍 快速开始 测试 四.ProtoStuff 介绍 快速 ...

  6. java json太长_修复Long类型太长,而Java序列化JSON丢失精度问题的方法

    Java序列化JSON时long型数值,会出现精度丢失的问题. 原因: java中得long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值). 解决办法一: 使用 ...

  7. kryo java_优化Java序列化– Java,XML,JSON,Kryo,POF

    kryo java 也许我很天真,但是我一直认为Java序列化肯定是将Java对象序列化为二进制形式的最快,最有效的方法. 毕竟Java是第7个主要发行版,所以这不是新技术,而且由于每个JDK似乎都比 ...

  8. 优化Java序列化– Java,XML,JSON,Kryo,POF

    也许我很天真,但是我一直认为Java序列化肯定是将Java对象序列化为二进制形式的最快,最有效的方法. 毕竟Java是第7个主要发行版,所以这不是新技术,并且由于每个JDK似乎都比上一个快,因此我错误 ...

  9. biginteger和long精度_修复Long类型太长,而Java序列化JSON丢失精度问题的方法

    造成原因:JS内置有32位整数,而number类型的安全整数是53位.如果超过53位,则精度会丢失.正如现在后台传来一个64位的Long型整数,因此超过了53位,所以后台返回的值和前台获取的值会不一样 ...

最新文章

  1. 关于Visual Studio 2010与64位系统的问题
  2. 使用8位字节的编码格式将字节流安全的转换成String
  3. ProtoBuf中的编码
  4. DOM操作中,遍历动态集合的注意事项。ex: elem.children
  5. 网络编程(part5)--文件读写偏移量及文件描述符
  6. visio科学图形包_科学网—科研必备:几款好用的流程图工具,助力你的论文/科研绘图...
  7. 老年人手里有多少积蓄,该不该告诉子女?
  8. [转载] pandas将Series变成键值对
  9. There is no Action mapped for namespace / and action name .
  10. 樱花漫地集于我心,蝶舞纷飞祈愿相随---总结 适者:survival of the fittest 适者:survival of the fittest...
  11. 我的第一份博客,测试一下:P
  12. 阶段5 3.微服务项目【学成在线】_day01 搭建环境 CMS服务端开发_14-MongoDb入门-文档...
  13. day_4 Selenium请求库
  14. IC基础知识3-输入阻抗和输出阻抗
  15. pta算法:计算天数
  16. 那时候的漫画【怀旧贴】
  17. 虚拟主机服务器错误500解决方法
  18. 我国新冠疫苗首批预计接种5000万人次,2月15日前完成
  19. Visual Studio 2017 version 15.9 官方最新版本下载(含那个啥码)
  20. day81_babasport第七天

热门文章

  1. 英特尔发布全新显卡品牌“锐炫” 首款显卡将于 2022 年上市
  2. 苹果抢安卓用户出“杀手锏”,连安卓手机App都能一键同步
  3. 交个朋友回应罗永浩撰文事故:系没有处理好内部流程导致的误解
  4. 岳云鹏:买128G手机仅112G可用!手机系统占用存储空间应厂商消化?
  5. 大佬就是有想法!比尔盖茨办公室曝光:实体版元素周期表震撼!
  6. 英雄互娱:中止代理的《NBA LIVE》在中国大陆地区所有推广活动
  7. 美团点评成中国第三大互联网公司!
  8. 办公室小野与爆米花视频身亡女孩家属和解:补偿金额保密
  9. 这款手机开卖在即却预约不足千人 网友:原来它还没凉?
  10. 消息称小米之家全面取消员工销售提成 回应:内容严重偏颇失实