ProtoBuf序列化协议简介

首先,常见的序列化方法主要有以下几种:

  • TLV编码及其变体(tag, length, value): 比如ProtoBuf。
  • 文本流编码:XML/JSON
  • 固定结构编码:基本原理是,协议约定了传输字段类型和字段含义,和TLV类似,但是没有tag和length,只有value,比如TCP/IP
  • 内存dump:基本原理是,把内存中的数据直接输出,不做任何序列化操作。反序列化的时候,直接还原内存。

常见序列化方法

  1. XML可扩展标记语言(eXtensible Markup Language)。是一种通用和重量级的数据交换格式,以文本方式存储。
  2. JSON(JavaScript ObjectNotation, JS对象简谱)是一种通用和轻量级的数据交换格式,以文本结构进行存储。
  3. Protocol Buffer是Google的一种独立的轻量级的数据交换格式,以二进制结构进行存储。

序列化结果比较

XML:

在这里插入图片描述

JSON:
在这里插入图片描述

Protocol Buffer:

在这里插入图片描述

ProtoBuf使用

Protocol buffers 在序列化数据方面,它是灵活的,高效的。相比于 XML 来说,Protocol buffers 更加小巧,更加快速,更加简单。⼀旦定义了要处理的数据的数据结构之后,就可以利用 Protocol buffers 的代码生成工具生成相关的代码。甚至可以在无需重新部署程序的情况下更新数据结构。只需使用Protobuf 对数据结构进行⼀次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写。

Protocol buffers 很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

ProtoBuf option部分选项
  • SPEED: 表示生成的代码运行效率高,但是由此生成的代码编译后会占用更多的空间。
  • CODE_SIZE: 和SPEED恰恰相反,代码运行效率低,但是生成的代码编译后占用更少的空间,通常用于资源有限的平台,比如Moblie。
  • LITE_RUNTIME: 生成的代码运行效率更高,同时生成的代码编译后所占用的空间也很少。这是牺牲protobuf提供的反射功能为代价。因此在C++中链接Protocol Buffer库时进需要链接libprotobuf-lite,而非libprotobuf

ProtoBuf编码

Variants编码(变长的类型使用)

为什么设计变长编码:普通的 int 数据类型, 无论其值的大小, 所占用的存储空间都是相等的,比如不管是0x12345678 还是0x12都占用4字节,那能否让0x12在表示的时候只占用1个字节呢?

是否可以根据数值的大小来动态地占用存储空间, 使得值比较小的数字占用较少的字节数, 值相对比较大的数字占用较多的字节数, 这即是变长整型编码的基本思想。

采用变长整型编码的数字, 其占用的字节数不是完全⼀致的, Varints 编码使用每个字节的最高有效位作为标志位, 而剩余的 7 位以⼆进制补码的形式来存储数字值本身, 当最高有效位为 1 时, 代表其后还跟有字节, 当最高有效位为 0 时, 代表已经是该数字的最后的⼀个字节。

在 Protobuf 中, 使用的是 Base128 Varints 编码, 在这种方式中, 使用 7 bit (即2的7次方为128)来存储数字, 在 Protobuf 中, Base128 Varints 采用的是小端序, 即数字的低位存放在高地址, 举例来看, 对于数字 1, 我们假设 int 类型占 4 个字节, 以标准的整型存储, 其⼆进制表示应为

00000000 00000000 00000000 00000001

可见,只有最后一个字节存储了有效数值,前三个字节都为0,若采用Variants编码,其二进制形式为

00000001

因为其没有后续字节,因此最高有效位为0,其余的7位以补码形式存放1,再比如数字666:在这里插入图片描述

Zigzag编码(针对负数)

Varints 编码的实质在于去掉数字开头的 0, 因此可缩短数字所占的存储字节数, 在上面的例子中, 只举例说明了正数的 Varints 编码, 但如果数字为负数, 则采用 Varints 编码会恒定占用 10 个字节, 原因在于负数的符号位为 1, 对于负数其从符号位开始的高位均为 1, 在 Protobuf 的具体实现中, 会将此视为⼀个很大的无符号数。

Varints 编码的实质在于设法移除数字开头的 0 比特, 而对于负数, 由于其数字高位都是 1, 因此 Varints 编码在此场景下失效

Zigzag 编码便是为了解决这个问题, Zigzag 编码的大致思想是首先对负数做⼀次变换, 将其映射为⼀个正数, 变换以后便可以使用Varints 编码进行压缩, 这里关键的⼀点在于变换的算法, 首先算法必须是可逆的, 即可以根据变换后 的值计算出原始值 , 否则就无法解码, 同时要求变换算法要尽可能简单, 以避免影响Protobuf编码、解码的速度。解码方式为:

在这里插入图片描述

数据组织

Protobuf 不是完全自描述的信息描述格式, 接收端需要有相应的解码器(即 proto 定义)才可解析数据格式, 序列化后的 Protobuf 数据不携带字段名, 只使用字段编号来标识⼀个字段, 因此更改 proto 的字段名不会影响数据解析(但这显然不是⼀种好的行为), 字段编号会被编码进⼆进制的消息结构中, 因此我们应尽可能地使用小字段编号。

同时,Protobuf 是⼀种紧密的消息结构, 编码后字段之间没有间隔, 每个字段头由两部分组成: 字段编号和 wire type, 字段头可确定数据段的长度, 因此其字段之前无需加入间隔, 也无需引入特定的数据来标记字段末尾, 因此 Protobuf 的编码长度短, 传输效率高。

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

家庭财务新助手,记录收支明细,一键导出表格,让您的家庭财务一目了然!

在繁忙的现代生活中,家庭财务管理常常成为一项令人头疼的任务。如何记录每一笔收支,如何清晰地掌握家庭财务状况,如何合理规划未来开支,这些都是我们需要面对的问题。然而,有了这款家庭财务助手——晨曦记账本&#xf…

【启明智显产品介绍】Model3工业级HMI芯片详解系列专题(一):芯片性能

Model3工业级跨界MCU是一款国产自主的基于RISC-V架构的高性能芯片,内置平头哥玄铁E907,主频480MHz,片上1MB大容量SRAM以及64Mb PSRAM。 Model3工业级MCU具有丰富的屏接口、高分辨率PWM和多路高精度定时器,可以处理各类实时数据与实…

录屏软件OBS简单使用

录屏软件OBS简单使用 官网下载地址: https://obsproject.com/ window解压直接使用版: 链接: https://pan.baidu.com/s/1495KDkvuDnjqdOvm1IG4Fw 提取码: 9xcr 复制这段内容后打开百度网盘手机App,操作更方便哦 简单使用 解压 解压window解…

深度学习(十一)——神经网络:线形层及其他层介绍

一、正则化层中nn.BatchNorm2d简介 主要作用:对输入函数采用正则化。正则化的主要作用是加快神经网络的训练速度。 class torch.nn.BatchNorm2d(num_features, eps1e-05, momentum0.1, affineTrue, track_running_statsTrue, deviceNone, dtypeNone)输入参数&…

大模型学习路线,存下吧很难找全的

随着人工智能技术的飞速发展,大模型在自然语言处理、计算机视觉、推荐系统等领域取得了显著成果。越来越多的学者和开发者开始关注并投身于大模型的研究与应用。本文将以大模型学习路线为核心,为您介绍从入门到精通所需掌握的知识和技能。 一、入门篇 …

Springboot整合Zookeeper分布式组件实例

一、Zookeeper概述 1.1 Zookeeper的定义 Zookeeper是一个开源的分布式协调服务,主要用于分布式应用程序中的协调管理。它由Apache软件基金会维护,是Hadoop生态系统中的重要成员。Zookeeper提供了一个高效且可靠的分布式锁服务,以及群集管理…

基于Vue3.0 Node.js 的 大文件切片上传、秒传、断点续传实现方案梳理

✨💻 在处理大文件上传时,切片上传是提高效率与用户体验的关键技术之一。下面将详细介绍如何在前端利用Vue框架与Node.js后端配合,实现这一功能。 👆🏻大体流程 👆🏻一、文件切片上传 通过文件…

力扣每日一题 6/11 暴力搜索

博客主页:誓则盟约系列专栏:IT竞赛 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 419.甲板上的战舰[中等] 题目: 给你一个大小为 m x n 的矩阵 b…

OAK-D-Long-Range: 让你的机器人拥有鹰一样的视觉!3D视觉精度与点云方案!

OAK-D LONG RANGE – 精度与点云 有没有想过让你的机器人有鹰的视力?来看看我们OAK-D-Long Range相机吧!这是一款3DAI相机,为全球项目带来了超强的视觉效果!让我们深入了解它是如何通过15cm的基线做到这一点的! 15CM…

Boosting Weakly-Supervised Temporal Action Localization with Text Information

标题:利用文本信息增强弱监督时间动作定位 源文链接:https://openaccess.thecvf.com/content/CVPR2023/papers/Li_Boosting_Weakly-Supervised_Temporal_Action_Localization_With_Text_Information_CVPR_2023_paper.pdfhttps://openaccess.thecvf.com/…

Python3 Matplotlib展示数据

matplotlib 是一个 Python 库,用于创建各种类型的图表和可视化。它提供了一个类似于 MATLAB 的绘图界面,使用户能够轻松地绘制线图、散点图、直方图、饼图等各种图表类型。matplotlib 可以在 Python 脚本、IPython shell、Jupyter Notebook 等环境中使用…

科技赋能冷链园区:可视化带来全新体验

应用图扑可视化技术,冷链园区能够更加直观地监控和管理资源,优化运作流程,提高运营效率与服务质量。

贪心算法学习四

例题一 解法(暴⼒解法 -> 贪⼼): 暴⼒解法: a. 依次枚举所有的起点; b. 从起点开始,模拟⼀遍加油的流程 贪⼼优化: 我们发现,当从 i 位置出发,⾛了 step 步…

怎么把webp文件转换为jpg?快来试试这四种转换方法!

怎么把webp文件转换为jpg?Webp是一种不常见的图片格式,这种格式在使用过程中有很多缺点,首先它的浏览器兼容性不是很强,这就代表大家无法随意进行网络传输,可能需要准备特定的操作才能进行,然后编辑webp的工…

查看服务器端口,如何查看服务器端口是多少并修改

查看服务器端口并修改内容是一个涉及网络管理和系统配置的专业任务。以下是一个详细的步骤说明,用于查看和修改服务器端口。 一、查看服务器端口 1. 使用命令行工具: - 对于Linux或Unix系统,可以使用netstat、lsof或ss等命令来查看端口状…

机器学习常见的sampling策略 附PyTorch实现

初始工作 定义一个模拟的长尾数据集 import torch import numpy as np import random from torch.utils.data import Dataset, DataLoadernp.random.seed(0) random.seed(0) torch.manual_seed(0) class LongTailDataset(Dataset):def __init__(self, num_classes25, max_sam…

数据结构---二叉树的性质总结

第i层上的节点数 证明: 二叉树的最大节点数 证明: 第一层对应2^0个节点, 累加得到 这是一个等比数列 求和公式: 那么这里的n指的是一共有多少个相加 根据从b到a一共有b-a1个可推出 有(k-1)-01个相加 那么结果为: 叶节点与度为2的节点关系 证明: 假设二叉树的总节点数为 NNN…

SolidWorks科研版更快地开发产品创意

在当今竞争激烈的市场环境中,产品创新的速度和质量直接决定了企业的生死存亡。对于科研人员和设计师来说,如何能够快速、准确地实现产品创意的转化,是摆在面前的一大挑战。SolidWorks科研版作为一款功能强大的三维设计软件,为科研…

正则表达式之三剑客grep

正则表达式匹配的是文本内容,linux的文本三剑客 都是针对文本内容 grep 过滤文本内容 sed 针对文本内容进行增删改查 awk 按行取列 文本三剑客都是按行进行匹配。 grep grep 的作用就是使用正则表达式来匹配文本内容 选项: -m …

Ubuntu-基础工具配置

基础工具配置 点击左下角 在弹出界面中点击 以下命令都是在上面这个界面执行(请大家注意空格) 命令输入完后,回车键就是执行,系统会提示输入密码(就是你登录的密码) 1.安装net工具 :(ifconfi…