当前位置: 首页 > news >正文

Protobuf 和JSON 性能分析

文章目录

    • 什么是协议缓冲区?
    • 如何定义协议缓冲区消息
      • 字段名称
      • 字段类型
      • 字段编号
      • 字段规则
      • 注释
    • protobuf 消息是如何压缩的?
    • protobuf 的优点
    • protobuf的缺点

传送门 ==>> AutoSAR入门和实战系列总目录

协议缓冲区或 Protobuf 是一种二进制格式,由 Google 创建,用于序列化在服务之间传输的结构化数据。

在我们了解什么是协议缓冲区之前,让我们先了解一下 JSON。JSON 在数据交换格式方面显然具有很大的优势,例如:

  • 网络上广泛接受的格式
  • 可以被所有语言阅读
  • 可以通过网络轻松共享
  • 数据可以是任何类型(嵌套元素、数组等)
  • 人类可读

但它也有一些缺点:

  • 架构未强制执行
  • 由于重复的键,对象可能很大
  • 不支持评论、元数据或文档

牢记这些,现在让我们看一下 protobuf 是什么以及它如何尝试解决这些缺点。

什么是协议缓冲区?

从官方页面:

协议缓冲区是 GOOGLE 用于序列化结构化数据的语言中立、平台中立、可扩展机制——想想 XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言。

因此,协议缓冲区是一种有效编码结构化数据的方法。它提供了通过使用规范语言定义其模式来创建数据结构的灵活性。规范语言不是用任何语言编写的,您可以使用 proto 文件语法定义消息。

这些消息用于以特定格式对数据进行编码,以使消息大小更小。在了解优化之前,让我们先看一下模式定义本身。

如何定义协议缓冲区消息

让我们为博客文章定义一个消息定义。我们将在其上指定 3 个字段名称,标题、作者和正文。

syntax = "proto3";

message BlogPost {
  required title string = 1;
  required author string = 2;
  optional body string = 3;
}

这是在 .proto 文本文件中定义的。上面的消息定义中嵌入了很多功能。

字段名称

字段名称必须全部小写。这是 protoc 编译器规定的约定。

字段类型

我们通过指定字段名称的数据类型来获得完全类型化的数据,可以是标量类型(int32、bool、string、float 等)或复合类型,包括枚举类型和其他消息类型。

字段编号

右侧的数字是每个字段名称唯一的字段编号。正如我们之前所了解的,protobuf 将我们的数据转换为二进制格式,因此这些数字用于识别我们创建的二进制消息中的字段。一旦我们开始使用消息类型,就不应更改字段编号,因为这会导致向后兼容性问题。该数字可以在 1 到 2^29-1 的范围内。

字段规则

这些消息还分配有字段规则,让我们可以指定该字段是必需的、可选的还是重复的。重复字段用于定义数组或列表。

注释

我们还可以通过使用单行 (//) 和多行注释定义 (/* */) 在消息定义中添加文档。

这是一个类型的示例模式文件,我们不需要每次都手动创建它。它可以使用自动生成工具创建,具体取决于我们实现 protobuf 的编程语言。

其他需要了解的有用信息是:

  • 可以在同一个 .proto 文件中定义多种类型
  • 类型可以相互嵌套
  • 也可以在不同的 .proto 文件中导入类型(导入语句需要来自项目根目录的相对路径)

protobuf 消息是如何压缩的?

既然我们知道了如何为协议缓冲区消息创建模式,那么对它进行了哪些优化以使其比 XML 和 JSON 更快?

协议缓冲区的一个关键特性是它们将消息的上下文与消息包含的数据分开。

所以对于 JSON 消息:

{
  "author" : "saransh",
  "title" : "protobuf"
}

根据我们上面的消息定义,相应的协议缓冲区(为了我们的理解在字符串中)将是:

127saransh228protobuf

正如我们所看到的,protocol buffer 消息要短得多,并且不包含任何可以从 proto 文件本身推断出的额外元信息。因此,protobuf 消息更小,也更容易解析。另外,当它们转换为二进制时,它们会进一步提高性能。

输出消息的可读性较差,需要了解要破译的 protobuf 编码,但这是我们为提高效率而付出的代价。让我们打破 protobuf 消息以了解它的含义:

消息的每个段的结构如下:

{field_number}{field_type}{data}

字段编号是分配给 .proto 文件中的字段名称的编号。字段类型是我们为它定义的类型的表示。在我们的例子中,它是一个字符串,它是一个可变长度的字段。这也意味着将分配给该字段的值不是像整数那样的固定宽度构造。所以我们需要指定我们还必须提供下一个长度。从而"author": "saransh"变成127saransh。如果您想了解更多,可以在网站上详细阅读有关编码的更多信息。

因此,我们不需要携带字段的整个定义,只需要三个数字来定义消息的上下文以及字段映射到的值。因此,与其他序列化方法相比,整个过程在大小和速度方面都变得更加高效。

protobuf 的优点

  • 数据完全输入
  • 数据自动压缩
  • 文档可以嵌入到模式定义中
  • 语言不可知(所有主要语言都支持)
  • Schema 可以随着时间以安全的方式发展(确保向后兼容性)
  • 比 XML 小 3-10 倍,速度快 20-100 倍
  • 可以为您自动生成代码
  • 需要更少的用于数据类型检查的样板代码

protobuf的缺点

  • 需要Schema来生成代码和读取数据
  • 序列化数据不是人类可读的
  • 可能缺少对某些语言的支持(尽管其中大多数确实存在)

如果平台(例如发出 Web 请求)不支持协议缓冲区的二进制格式,则协议缓冲区中有能力将二进制消息序列化为字符串,以确保传输安全。这使得它也可用于这些场景,尽管协议缓冲区的大多数用例都围绕微服务和 gRPC 调用。

最后,需要考虑所有这些权衡并做出选择一件事而不是另一件事的决定。但是很高兴了解那里的各种技术,这篇文章旨在让您了解它。如果您喜欢这篇文章,请在下面发表评论,让我们知道!

相关文章:

  • DCA培训心得笔记(二)
  • TB-RK1808M0最新固件烧录和驱动更新
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • C语言被创造出来的基础是什么?它的主要结构是什么?
  • error: Unexpected console statement (no-console) 解决办法
  • 神经系统分类和组成图表,神经系统的组成概念图
  • [Swift学习] 访问控制 Access Control, private、public、filePrivate等修饰符
  • [SQL]数据库语言学习
  • 软考高频考点——项目中标了以后该怎么做?
  • 基于注意力机制的LSTM液体管道非稳态工况检测
  • Oracle VM VirtualBox安装CentOS 7系统
  • windows hello人脸识别设置没反应的解决办法
  • 企业级容器云PaaS解决方案【厚PaaS+轻应用+微服务】---(2)
  • dubbo 利用分组区分同一个服务的不同实现
  • npm下载的包分类
  • [译]前端离线指南(上)
  • Bytom交易说明(账户管理模式)
  • JS+CSS实现数字滚动
  • js写一个简单的选项卡
  • SpiderData 2019年2月16日 DApp数据排行榜
  • Twitter赢在开放,三年创造奇迹
  • 猴子数据域名防封接口降低小说被封的风险
  • 前嗅ForeSpider采集配置界面介绍
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 系统认识JavaScript正则表达式
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​插件化DPI在商用WIFI中的价值
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • #include<初见C语言之指针(5)>
  • #includecmath
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (四)Controller接口控制器详解(三)
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .“空心村”成因分析及解决对策122344
  • .NET : 在VS2008中计算代码度量值
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net6 Api Swagger配置
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .NET中使用Redis (二)
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • .sys文件乱码_python vscode输出乱码
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @property @synthesize @dynamic 及相关属性作用探究
  • @staticmethod和@classmethod的作用与区别