1. 首页
  2. 综合百科
  3. Protobuf 为啥比 JSON、XML 牛

Protobuf 为啥比 JSON、XML 牛

简介:关于Protobuf 为啥比 JSON、XML 牛的相关疑问,相信很多朋友对此并不是非常清楚,为了帮助大家了解相关知识要点,小编为大家整理出如下讲解内容,希望下面的内容对大家有帮助!
如果有更好的建议或者想看更多关于综合百科技术大全及相关资讯,可以多多关注茶馆百科网。

文章目录

看表面缺失“结构”来描述Protobuf1。类型和顺序2。Varint3。长度定义的4。浮点数5.sint32/sint64汇总热答:

今天。我带你深入了解Protobuf。如果你不熟悉Protobuf的用法。直达:developers.google.com/protocol-bu.

当你对Protobuf有了基本的了解。你会明白Protobuf序列化数据会比JSON和XML更高效。

那为什么高?本文就带着这个问题一探究竟。

看表面

用于JSON,XML。以便于数据传输的可读性。数据的结构化信息被保留。以JSON为例。如下:{ '姓名' '老苗''年龄'18}发送此信息时复制代码。收件人收到后就明白了。这是“键/值”形式的数据。而“名字”后面是名字。“年龄”之后就是年龄。

那么如何压缩数据呢?

我们可以删除花括号,姓名,年龄和其他结构数据,如冒号,逗号和引号。老苗18抄袭了代码,所以这样删了。接收者如何知道?哪个是名字?哪个是年龄?

删除”结构“

只需要发送方和接收方保持这个数据的“结构”。发送方只发送数据。在接收器接收到数据之后。按照本地保留的“结构”解析数据就可以了。

假设。“结构”如下。这不是真的。只是为了描述方便。{namestring7ageint1}复制的代码可以通过这个“结构”得知:

姓名数据在年龄数据之前。名称数据类型是字符串。年龄数据类型为int。名称数据字节长度为7。年龄数据字节长度为1。接收者只需要持有这个“结构”就知道如何分析“老庙18”数据。

自描述

但是仍然存在这些问题:

名字数据超过7个字节怎么办?年龄数据超过1字节怎么办?结构中的顺序不能调整。太死了。我们做什么呢当然可以。发送方和接收方都更新自己的“结构”数据。但这显然不现实。因为你不能保证数据是固定长度的。

对于年龄数据。我们可以定义为4字节或者8字节。只要你能处理好自己的事情。但还是有问题。浪费空间?

假设。年龄定义为4个字节。传输的数据是18。对于数字18。只有一个字节就够了。剩余的三个字节被浪费了。但是我们不能定义为1个字节。因为可能数量很大。

那么如何压缩年龄数据呢?

对于Protobuf。解决上述问题的信息将被添加到数据中。也就是数据描述自己。“自我描述”的简称。

Protobuf做了什么?如下所示:

按“字段”顺序排列的信息被添加到数据中。向数据中添加类型信息。最小化压缩整形数据。序列化数据时

Protobuf

Protobuf。Protobuf数据类型分为六类。它在英语中被称为“wiretype”。

“wiretype”中的类型“3”和“4”已被弃用。这一块就不解释了。

我们通过一个消息消息展开解释。如下:messagehellorequest { string name=1;int 32 num=2;float height=3;repeatedint32hobbies爱好=4;}复制代码。就像我上面说的“结构”。发送方和接收方正是通过这种结构来解析数据的。现在我们将逐一解释上面遗留的问题。

1.类型和顺序

如何保存传输数据中的“数据类型”和“顺序”?

数据类型对应于“wiretype”。该顺序对应于“字段编号”。如果int32num=2对应于以下情况:

导线类型:0 .通过上表对应。字段编号:2 .字段后的唯一代码。将这两条信息按照以下公式组装:(field_number3)|wire_type复制代码带入:(23)|016复制代码

2.Varint

如何压缩num字段保存的数据?如果num中存储的数据是300。它以4个字节存储如下:00000000000000000000100101100复制代码从结果中可以看出。真实有效的数据只有2个字节。为了压缩。面对不同的数据大小,会占用未使用的字节。

那怎么记录数据长度呢?我们可以再增加一个字节来记录真实数据所占用的实际字节数。300个数据。将记录长度增加一个字节。那么数据总共需要3个字节。有什么方法可以减少字节数?

当然会有。不然我就说一大堆废话。我们继续吧。

请介绍一下Varint算法。

。过程如下:
将数据以7位为一组进行分割;将组的顺序颠倒。即:将”高位→低位“规则。改为”低位→高位“;识别每一组。如果该组后还有数据。就在该组前增加一位”1”。否则增加“0”。将数据300带入该算法。过程如下:
300:00000000000000000000000100101100→7位分割:00000000000000000000000100101100→颠倒顺序:0101100000001000000000000→组前加1/0:1010110000000010→十进制:1722复制代码
按照这套算法下来。将数据压缩为2个字节存储。而接收方拿到字节数据后。只需要按照高位识别。如果为0。说明之后没有数据了。
最终。对于int32num=2结构和数据300。压缩后的结果为:
161722复制代码

3.Length-delimited

现在说说stringname=1。该类型对应的“wiretype”为2。”fieldnumber”为2。记录“顺序”和“类型”方式和上面讲的一样。
重点说说数据如何记录。相比Varint算法。该类型就简单多了。只需要使用Varint算法记录数据的字节长度。
假如。name的值为“miao”。最终结果为:
10410910597111复制代码
解释:
10:(2<<3)|2。4:字符串长度。之后:按照“UTF-8”编码保存。对于message嵌套、repeated(数组或切片)、字节数组。也是按照该算法得到。
例如。repeatedint32hobbies=4。假设hobbies数据为[10,20]。最终结果为:
3421020复制代码

4.浮点数

针对浮点类型。就更简单了。浮点数据使用固定字节保存。记录“顺序”和“类型”依然是上面讲的。
假如。floatheight=3。该类型对应的“wiretype”为5。数据假设为52.1。最终结果为:
291021028066复制代码
解释:
29:(3<<3)|5。之后:使用固定字节数4。如果使用了双精度。那对应的“wiretype”为1。数据占用字节数为8。

5.sint32/sint64

这两个类型不知道你在写proto文件时有没有用到。明白这个很重要。不然有时候数据就不能起被到压缩的作用。
上面讲到的Varint算法中。我们知道了以7位一组。再增加一位“识别位”来起到压缩数据的作用。但存在一个问题。倘若存在负数时。那这种压缩方式就失效了。
至于为啥?如何解决的?
我先说结果。如果写proto文件时。设置的数据类型为sint32或sint64时。将采用ZigZag算法进行数据压缩。
ZigZag算法我就不重复讲解了。直接看上一篇。

小结

学完本篇我们知道了Protobuf怎么做到了压缩数据。简单说下。就是删除一些没用的信息。采用自描述的方式记录“类型”、“顺序”、“数据”。
而对于类型。只记录了“wiretype”。该类型确定了数据的大概处理方式。
那说它就一定比JSON、XML好吗?也不是。
因为要采用Protobuf方式传输数据。发送方和接收方必须采用同一套结构规则。也可以说“协议”。所以。如果想提高数据的阅读性。降低这种规则的配合。就可以使用JSON、XML。
后面我会使用Go语言实现Protobuf序列化和反序列化的核心算法。只要这样我才觉得真的明白了该算法的真谛。

本文主要介绍了关于Protobuf 为啥比 JSON、XML 牛的相关养殖或种植技术,综合百科栏目还介绍了该行业生产经营方式及经营管理,关注综合百科发展动向,注重系统性、科学性、实用性和先进性,内容全面新颖、重点突出、通俗易懂,全面给您讲解综合百科技术怎么管理的要点,是您综合百科致富的点金石。
以上文章来自互联网,不代表本人立场,如需删除,请注明该网址:http://seotea.com/article/886478.html