高效的ProtoBuf

news2024/11/19 11:28:09

一、背景

Google ProtoBuf介绍 这篇文章我们讲了怎么使用ProtoBuf进行序列化,但ProtoBuf怎么做到最高效的,它的数据又是如何压缩的,下面先看一个例子,然后再讲ProtoBuf压缩机制。

二、案例

网上有各种序列化方式性能对比,我们这里仅对比一下JSON序列化和ProtoBuf序列化。

原始数据如下

{
"id":1,
"name":"qingcai18036",
"email":"qingcai18036@yeah.net"
}

序列化后十六进值如下

可以看出使用ProtoBuf序列化后的十六进值长度要小很多。

三、基础概念

1、大小端模式

大端模式:数据的高字节保存在内存低地址中,数据的低字节保存在内存高地址中。

小端模式:数据的高字节保存在内存高地址中,数据的低字节保存在内存的低地址中。

这里记住小端模式的存储是 高高低低,小端模式也是ProtoBuf协议中使用的模式。

十六进制数据  0x12345678,大小端模式在内存的存放如下

2、ZigZag编码

ZigZag是一种对负数友好的压缩算法,可以压缩掉多余为0的比特位。

正数:byte a = 11;   存储用原码表示二进制值:0000 1011

ZigZag对正数进行编码

        整体数据左移1位:    0001 0110

        符号位移到最低位  :0001 0110

负数:byte a =-11;    存储用补码表示二进值 :11110101

          原码:10001011->  反码:11110100->   补码:11110101

ZigZag对负数进行编码

       (1)、左移1位:11101010

       (2)、符号位移到最低位:11101011

       (3)、除最后一位外全部取反:00010101

ZigZag 对负数-11增加了前导三个0,可以压缩掉

3、 Varint编码

Varint是一种使用一个或多个字节序列化整数的办法,对于32位的整数用Varint编码后为1~5个字节,小的数字使用1个byte,大的数字使用5个byte。但实际场景中小数字使用率大于大数字,这样就达到压缩效果,而Java序列化Int需要用4个byte。

Varint每个字节中每一比特位定义

第8位(最高位):1:表示后续的字节也是该数字的一部分 0:表示该数字结束。

第1~7位:表示具体数字值

Varint编码例子

小于128的数字用一个字节就可以表示,大于128的数比如1234,需要用到2个字节表示。

1234  二进制值  10011010010

在Java中Int类型占用4个字节,如果直接使用Java序列化存储如下

00000000 00000000  00000100 11010010

前面有21个0造成空间的浪费,可以对空位(0)进行压缩,节省空间。

Varint编码:从右往左每隔7位取一片段并补上标识位,再将若干片段从左往右排序。

(1)、从右往左取7位  1010010,并补上标记位(1表示后续还有数据)  11010010

(2)、再续继取7位     000100 1,并补上标记位(0表示后续没有数据)00001001

(3)、再往左已经全部是0了,就不管了。

(4)、然后将上面形成的两个片段从左往右排列(小端模式)   11010010 00001001

最终整数1234做Varint编码后二进制为  11010010 00001001

四、ProtoBuf协议

1、ProtoBuf序列结构

2、Key定义: (field_number << 3) | wire_type

                        field_number 是 定义在proto文件中字段的序号

3、wire_type

  • Type=1 :如果是 int32采用Varints编码编码,如果是sint32采用ZigZag编码(因为要对负数进行有效压缩)。

  • Type=1:分配64位大小空间,采用小端模式

  • Type=5:分配32位大小空间,采用小端模式

  • Type=2:string是一个指定长度的编码,key+length+content,key编码采用统一的方式,length(内容长度)采用varints编码,content就是由length指定长度的byte。所以其对字符串本身的内容并不压缩?

五、总结

ProtoBuf采用了Varint、ZigZa压缩算法,二制制的数据就非常紧凑,并且比JSON少了{}符号、字段名、所以用ProtoBuf序列化后整体体积会更小,这样网络传输更快,更高效。

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

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

相关文章

elment以及elementPlus选中组件出现黑框问题解决!!

目录 问题&#xff1a; 图示&#xff1a; 解决方案&#xff1a; 问题&#xff1a; 使用elementPlus的按钮组件&#xff0c;点击按钮后会出现黑框&#xff0c;除非点击其他地方才能取消掉&#xff08;之前使用elment-ui其它组件时也出现过&#xff09; 图示&#xff1a; 解决方案…

2023网络安全工程师可以考哪些证书?只学习不考证怎么行呢?

想入网安行业的小可爱们&#xff0c;如果你在疯狂学习知识技能的同时&#xff0c;也计划着考取一些证书当做入门的金钥匙&#x1f511;。 先别急&#xff0c;如果还没有进入网络安全工作岗位&#xff0c;那么&#xff0c;首要任务是打好基础&#xff0c;学好网络安全技术。若是…

docker容器启动成功外部访问不到

1.重启docker服务 systemctl restart docker

9张图深入剖析ConcurrentHashMap

前言 在日常的开发中&#xff0c;我们经常使用key-value键值对的HashMap&#xff0c;其使用哈希表实现&#xff0c;用空间换取时间&#xff0c;提升查询性能 但在多线程的并发场景中&#xff0c;HashMap并不是线程安全的 如果想使用线程安全的&#xff0c;可以使用Concurren…

Swing程序设计(5)绝对布局,流布局

文章目录 前言一、布局管理器二、介绍 1.绝对布局2.流布局总结 前言 Swing窗体中&#xff0c;每一个组件都有大小和具体的位置。而在容器中摆放各种组件时&#xff0c;很难判断其组件的具体位置和大小。即一个完整的界面中&#xff0c;往往有多个组件&#xff0c;那么如何将这…

R函数optim()最小化或者最大化多参数函数

一、optimize()最小化或者最大化单参数函数 1.1函数介绍 函数功能描述&#xff1a;给定一个单参数函数f&#xff0c;需要找到使得f达到其最小值或者最大值的点。 使用optimize()函数最小化单参数函数时&#xff0c;需要指定最小化的函数f及其定义域&#xff08;x的上界和下界…

Seata 源码篇之AT模式启动流程 - 中 - 03

Seata 源码篇之AT模式启动流程 - 中 - 03 数据源代理会话代理锁定查询执行器本地事务提交本地事务回滚 更新执行器删除执行器插入执行器 小节 本系列文章: Seata 源码篇之核心思想 - 01Seata 源码篇之AT模式启动流程 - 上 - 02 数据源代理 当我们的数据源被代理后&#xff0c…

[C]嵌入式中变量存储方案

#include<stdio.h>#define uint8_t unsigned char #define uint16_t unsigned short #define uint24_t unsigned int #define uint32_t unsigned int #define uint64_t unsigned long long//用户自定义变量名字&#xff0c;用于存储 typedef enum {first_run 0,//…

Linux: tcpdump抓包示例

文章目录 1. 前言2. TCP 状态机3. tcpdump 抓包示例3.1 抓连接握手包&#xff1a;三次握手3.2 抓数据包示例3.3 抓终结连接&#xff1a;四次挥手 4. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任…

【面试HOT100】哈希双指针滑动窗口

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于LeetCodeHot100进行的&#xff0c;每个知识点的修正和深入主要参考…

创建vue3工程

一、新建工程目录E:\vue\projectCode\npm-demo用Visual Studio Code 打开目录 二、点击新建文件夹按钮&#xff0c;新建vue3-01-core文件夹 三、右键vue3-01-core文件夹点击在集成终端中打开 四、初始化项目&#xff0c;输入npm init 一直敲回车直到创建成功如下图 npm init 五…

The directory ‘*‘ or its parent directory is not owned by the current user

python安装编译时出现如下错误 The directory /home/admin/.cache/pip/http or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may …

【办公软件】案例:电路中计算出的电阻值为5欧,怎么通过Excel匹配到仓库里最接近的电阻值?

在实际工作中&#xff0c;比如我们计算出一个电阻值为46欧&#xff0c;那么我们的库里到底是有哪个电阻值最接近呢&#xff1f;可能有一些有经验的工程师会说当然是47欧呀。 但是如果我们计算出来的是80.2欧呢&#xff1f;是不是得去查一下表格看看到底哪个最接近&#xff0c;…

PyTorch入门之【tensor】

目录 tensor的创建tensor的相关信息tensor的运算 tensor的创建 1.手动创建 import torch test1torch.tensor([1,2,3])#一维时为向量 test2torch.tensor([[1,2,3]])#二维时为矩阵 test3torch.tensor([[[1,2,3]]])#三维及以上统称为tensor print(test1) print(test2) print(tes…

C++ 类和对象篇(四) 构造函数

目录 一、概念 1. 构造函数是什么&#xff1f; 2. 为什么C要引入构造函数&#xff1f; 3. 怎么用构造函数&#xff1f; 3.1 创建构造函数 3.2 调用构造函数 二、构造函数的特性 三、构造函数对成员变量初始化 0. 对构造函数和成员变量分类 1. 带参构造函数对成员变量初始化 2. …

云存储解决方案-阿里云OSS

1. 阿里云OSS简介 阿里云对象存储服务&#xff08;Object Storage Service&#xff0c;简称OSS&#xff09;为用户提供基于网络的数据存取服务。使用OSS&#xff0c;用户可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种非结构化数据文件。 阿里云OSS将数据…

练[BJDCTF2020]Easy MD5

[BJDCTF2020]Easy MD5 文章目录 [BJDCTF2020]Easy MD5掌握知识解题思路关键paylaod 掌握知识 ​ 强等于和弱等于的MD5绕过&#xff0c;数据库查询的MD5加密绕过&#xff0c;代码审计 解题思路 打开题目链接&#xff0c;发现是一个post提交框&#xff0c;提交完了也就是url发…

自然语言处理 | WordNet

WordNet是词汇数据库,即英语词典,专为自然语言处理而设计。 Synset是一种特殊的简单接口,存在于 NLTK 中, 用于在 WordNet 中查找单词。同义词集实例是表达相同概念的同义词的分组。有些单词只有一个同义词集,有些则有多个。

【kubernetes】使用helm部署redis

1 什么是helm 在学习使用k8s进行应用的部署时&#xff0c;或者从github上下载一些组件进行部署时&#xff0c;通常是直接用yaml的方式部署&#xff0c;用这种方式部署时&#xff0c;有个比较大的问题是&#xff0c;当参数需要调整时&#xff0c;就需要阅读整个yaml文件&#x…

UG\NX CAM二次开发 加工模块获取 UF _ask_application_module

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 加工模块获取 UF _ask_application_module 代码: void MyClass::do_it() { // TODO: add your code here // 获取NX当前所在的模块 int module_id = 0; // UF_ask_application_module(&…