Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ProtoBuf试用与JSON的比较

ProtoBuf试用与JSON的比较

作者头像
Xiaolei123
修改于 2022-06-19 05:47:48
修改于 2022-06-19 05:47:48
8.2K00
代码可运行
举报
文章被收录于专栏:肖蕾的博客肖蕾的博客
运行总次数:0
代码可运行

介绍

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

同类

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

原理

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

ProtoBuf编译器安装

Mac : brew install protobuf

举个例子

1. 先创建一个proto文件

message.proto

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
syntax = "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;
    }
}
2. 创建一个Java项目

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

3. 编译proto文件至Java版本
  • 用命令行 cd 到 src/main 目录下
  • 终端执行命令 : protoc --java_out=./java ./proto/*.proto
  • 会发现,在你的src/main/java 里已经生成里对应的Java类
4. 依赖Java版本的ProtoBuf支持库

这里只举一个用Gradle使用依赖的栗子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
implementation 'com.google.protobuf:protobuf-java:3.9.1'
5. 将Java对象转为ProtoBuf数据
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
6. 将ProtoBuf数据,转换回Java对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JSON 开始编码 】
JSON 编码1次,耗时:22ms
JSON 数据长度:106
-开始解码-
JSON 解码1次,耗时:1ms

【 ProtoBuf 开始编码 】
ProtoBuf 编码1,耗时:32ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码1,耗时:3ms
  • 运行 10 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JSON 开始编码 】
JSON 编码10次,耗时:22ms
JSON 数据长度:106
-开始解码-
JSON 解码10次,耗时:4ms

【 ProtoBuf 开始编码 】
ProtoBuf 编码10,耗时:29ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码10,耗时:3ms
  • 运行 100 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JSON 开始编码 】
JSON 编码100次,耗时:32ms
JSON 数据长度:106
-开始解码-
JSON 解码100次,耗时:8ms

【 ProtoBuf 开始编码 】
ProtoBuf 编码100,耗时:31ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码100,耗时:4ms
  • 运行 1000 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JSON 开始编码 】
JSON 编码1000次,耗时:39ms
JSON 数据长度:106
-开始解码-
JSON 解码1000次,耗时:21ms

【 ProtoBuf 开始编码 】
ProtoBuf 编码1000,耗时:37ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码1000,耗时:8ms
  • 运行 1万 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
JSON 开始编码 】
JSON 编码10000次,耗时:126ms
JSON 数据长度:106
-开始解码-
JSON 解码10000次,耗时:93ms

【 ProtoBuf 开始编码 】
ProtoBuf 编码10000,耗时:49ms
ProtoBuf 数据长度:34
-开始解码-
ProtoBuf 解码10000,耗时:23ms
  • 运行 10万 次
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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字节数组数据,转换成对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Id:1994, Name:XIAOLEI
手机号:100860 (HOME)
手机号:100100 (MOBILE)
getNickname=

结果,是可以转换成功。

删除字段
  • 在proto文件中删除 name 字段
  • 生成Java文件
  • 用老proto字节数组数据,转换成对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Id:1994, Name:null
手机号:100860 (HOME)
手机号:100100 (MOBILE)

结果,是可以转换成功。

END

老群被封,+新Q群709287944

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.08.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Netty系列化之Google Protobuf编解码
Protobuf 简介Protobuf 下载Protobuf 安装编写message.proto文件编译message.proto文件编译后的得到的Message.java测试代码测试结果
黑洞代码
2021/01/14
1.2K0
【Android Protobuf 序列化】Protobuf 性能测试 ( fastjson 序列化与反序列化 | gson 序列化与反序列化 | 三种序列化与反序列化性能对比 )
在上一篇博客 【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 源码分析 | 创建 Protobuf 对象 ) 中 , 创建了 Protobuf 对象 , 本博客中将其序列化 , 保存到本地文件中 ;
韩曙亮
2023/03/29
2.3K0
Protobuf+Netty
Protobuf编写客户端Netty客户端客户端处理类Protobuf编写服务端netty服务端netty服务端处理类
黑洞代码
2021/01/14
8480
Google 开源技术protobuf
protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多。虽然是二进制数据格式,但并没有因此变得复杂,开发人员通过按照一定的语法定义结构化的消息格式,然后送给命令行工具,工具将自动生成相关的类,可以支持php、java、c++、python等语言环境。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作。
黄规速
2022/04/15
2.4K0
Google Protocol Buffers三两事【知识笔记】
小结:根据上图测评,序列化后的空间开销与解析性能上,Avro与Protobuf不相上下独占鳌头;另外根据“Protobuf协议介绍及性能实测”文中测评来看,报文在几千个字节以内,Protobuf与JSON/XML并没有太大优势,而hessian2表现更优秀;当报文大小超过10万字节,Protobuf性能是XML的3倍,是JSON的2倍,Hessian2的2倍;当报文大小超过10万字节,序列化后的字节大小约XML的1/4,约JOSN的1/2,约Hessian2的1/3;高性能原因Protobuf优化的二进制消息格式,JSON/XML是文本描述的;适用于性能要求高的RPC调用。
瓜农老梁
2020/04/07
1.2K0
Google Protocol Buffers三两事【知识笔记】
protobuf篇:介绍、安装、官方教程翻译、测试
综上所述目前最好的设计消息数据包方式是服务器和客户端通信协议推荐用protobuf,服务器存入数据库时用json。
看、未来
2021/10/28
1.7K0
protobuf篇:介绍、安装、官方教程翻译、测试
Android:手把手带你分析 Protocol Buffer使用 源码
通过将 结构化的数据 进行 串行化(序列化),从而实现 数据存储 / RPC 数据交换的功能
Carson.Ho
2019/02/22
1.9K0
protobuf使用简介
环境:windows,java 1. protobuf概述 protobuf是Google开发一种数据描述格式,能够将结构化数据序列化,可用于数据存储,通信协议等方面。 protobuf是以二进制来存储数据的。相对于JSON和XML具有以下优点: - 简洁 - 体积小:消息大小只需要XML的1/10 ~ 1/3 - 速度快:解析速度比XML快20 ~ 100倍 - 使用protobuf的编译器,可以生成更容易在编程中使用的数据访问代码 - 更好的兼容性,protobuf设计的一个原则就是要能够很好的支持向下或向上兼容 2. 下载,安装 在使用protobuf之前,需要安装protobuf编译器和运行时环境。 由于protobuf是跨平台,跨语言的,所以需要下载和安装对应版本的编译器和运行时依赖。 (1)protobuf编译器下载:https://github.com/google/protobuf/releases。 对于windows平台,下载:protoc-${version}-win32.zip。在此以protoc-3.3.0-win32.zip为例。 解压到指定目录,如:D:\protoc-3.3.0-win32。添加到windows环境变量:D:\protoc-3.3.0-win32\bin。 (2)protobuf运行时下载:protobuf运行时环境是区分不同语言的,针对不同语言的安装方式不同。 下载protobuf到指定目录:git clone https://github.com/google/protobuf.git,如:D:\protobuf。 对于java语言而言,可以通过maven将protobuf运行时依赖安装到本地仓库,详见:https://github.com/google/protobuf/tree/master/java。 需要注意的是,在执行:mvn install 之前,需要将protobuf编译器(在此即:D:\protoc-3.3.0-win32\bin\protoc.exe)拷贝到protobuf目录下的src路径下,即:D:\protobuf\src。 否则,在编译安装protobuf运行时环境时报错:
编程随笔
2019/09/11
2.3K0
protobuf使用简介
Protobuf: 高效数据传输的秘密武器
当涉及到网络通信和数据存储时,数据序列化一直都是一个重要的话题;特别是现在很多公司都在推行微服务,数据序列化更是重中之重,通常会选择使用 JSON 作为数据交换格式,且 JSON 已经成为业界的主流。但是 Google 这么大的公司使用的却是一种被称为 Protobuf 的数据交换格式,它是有什么优势吗?这篇文章介绍 Protobuf 的相关知识。
未读代码
2023/09/01
8290
Protobuf: 高效数据传输的秘密武器
Protocol Buffers(3):阅读一个二进制文件
编写addressbook.proto文件,在官方例子上略作修改,增加了float字段,以分析浮点数的存储方式。
李拜六不开鑫
2019/05/07
2.3K0
Protocol Buffers(3):阅读一个二进制文件
Go with Protobuf
本教程使用proto3向 Go 程序员介绍如何使用 protobuf。通过创建一个简单的示例应用程序,它向你展示了如何:
孟斯特
2023/10/08
3430
Go with Protobuf
[Protocol Buffer]Java使用Protocol Buffer
下面一个例子是一个简单的通讯录,可以读写人物信息到文件。每个人都有姓名,ID,email和电话号码。
wOw
2018/09/18
2.3K0
基于google protobuf的gRPC实现
Protobuf(Google Protocol Buffers)提供一种灵活、高效、自动化的机制,用于序列化结构数据。Protobuf仅需自定义一次所需要的数据格式,然后我们就可以使用Protobuf编译器自动生成各种语言的源码,方便我们读写自定义的格式化数据。另外Protobuf的使用与平台和语言无关,可以在不破坏原数据格式的基础上,扩展新的数据。
小一
2019/08/14
1.6K0
基于google protobuf的gRPC实现
Carson带你学序列化:Google出品的序列化神器Protocol Buffer使用攻略
通过将 结构化的数据 进行 串行化(序列化),从而实现 数据存储 / RPC 数据交换的功能
Carson.Ho
2022/03/25
1.4K0
Carson带你学序列化:Google出品的序列化神器Protocol Buffer使用攻略
【protobuf】三、proto3语法详解② -- enum、Any、oneof、map类型
​ 将两个“具有相同枚举值名称”的枚举类型放在单个 .proto 文件下测试时,编译后会报错:“某某某常量已经被定义”,所以这里要注意:
利刃大大
2025/02/03
1.1K0
【protobuf】三、proto3语法详解② -- enum、Any、oneof、map类型
Protobuf协议?盘他!
Protobuf是Google基于C++ 进行的实现的一套数据序列化/反序列化库,开发人员可以根据 ProtoBuf 的语言规范生成多种编程语言(C++、Python、Java 等)的接口代码。使用ProtoBuf的文件在存储效率上和处理性能上都元高于XML,也具有更好的跨平台性,使用灵活。
audy
2019/04/28
1.5K0
Protobuf协议?盘他!
google ProtoBuf开发者指南
目录1  概览1.1  什么是protocolbuffer1.2  他们如何工作1.3Python
Java架构师必看
2021/03/22
1.4K0
【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 使用文档 | 创建 Protobuf 源文件 | Protobuf 语法 )
Protobuf Java 语言对应用法 : https://developers.google.com/protocol-buffers/docs/javatutorial
韩曙亮
2023/03/29
1.3K0
【Android Protobuf 序列化】Protobuf 使用 ( Protobuf 使用文档 | 创建 Protobuf 源文件 | Protobuf 语法 )
你还在用 JSON?Protobuf 才是高效通信的王者!
特点:Protobuf 针对 不同的字段类型 采用 不同的编码方式 和数据存储方式,以确保得到高效紧凑的数据压缩。
IsLand1314
2025/07/21
1440
你还在用 JSON?Protobuf 才是高效通信的王者!
Google Protocol Buffers 数据交换协议
protobuf(Protocol Buffers)是Google推出的一个结构化数据交换协议,用于传递自定义的消息格式,可用于同一台机器的进程间、不同设备进程间的数据传递。protobuf是一种语言无关、平台无关、高效、扩展性良好的语言,提供了一种将结构化数据进行序列化和反序列化的方法。
Yano_nankai
2018/10/08
1.4K0
Google Protocol Buffers 数据交换协议
推荐阅读
相关推荐
Netty系列化之Google Protobuf编解码
更多 >
交个朋友
加入HAI高性能应用服务器交流群
探索HAI应用新境界 共享实践心得
加入[游戏服务器] 腾讯云官方交流站
游戏服运维小技巧 常见问题齐排查
加入[数据] 腾讯云技术交流站
获取数据实战干货 共享技术经验心得
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档