Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码

1  go grpc-go 相关技术专栏 总入口

2  Protobuf介绍与实战 图文专栏 文章目录

当数据类型为string,bytes,embedded messages,packed repeated fields时,

采用的是Length-delimited编码方式,即TLV结构;(TLV结构介绍,可参考前文)

整体采用的是TLV编码结构

但是,变量值V的编码方式是不同一的。

比方说

  • 当类型为string, bytes时,变量值采用的是UTF-8编码(我对UTF-8编码规则并不了解,这一点,仅个人猜测)
  • 当类型为embedded messages时,变量值采用的编码跟内嵌消息里的变量类型的编码保持一致(后面有例子)

1、当数据类型为string、bytes类型,变量值采用何种编码方式?

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第1张图片

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第2张图片

bytes,不再测试

2、当数据类型为embedded messages类型,变量值采用何种编码方式?

左侧是,单元测试用例

右侧是,proto测试文件

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第3张图片

字节比较多,先看前3个字节00010010 00000001 01100001

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第4张图片

此时,已经对变量Fstring进行了解码

接下来,看剩下的9个字节
00101010 00000111 00010000 10000001 00000001 01001010 00000010 01100001 00110001

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第5张图片

此时,已经获取到变量Fstatus的内容了,接下来,需要对此进行解码

继续看,剩下的7个字节:

先看前3个字节:00010000 10000001 00000001

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第6张图片

再看剩下的4个字节:01001010 00000010 01100001 00110001

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第7张图片

也就是说,嵌入消息里

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第8张图片

3、当使用packed repeated fields时,变量值采用何种编码方式

repeated,使用来创建数组的;

3.1、那么,packed是用来做什么的?

packed是打包的意思,
假设,未使用packed的话,repeated的编码结构可能如下:Tag-Length-Value-Tag-Length-Value-Tag-Length-Value…

,那么使用packed的话,repeated的编码结构可能如下:Tag-Length-Value-Value-Value…

因为,tag都是相同的字段,没必要多次传输,传输一次即可。

3.2、在protoc2版本中,测试paced功能?

当packed采用默认值的情况,即不显示设置packed值

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第9张图片

从结果中,可以看出来,tag部分,传输了3次,其实,传输一次即可。

3.2.1、当显示设置packed为false时的情况

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第10张图片

3.2.2、当显示设置packed为true时的情况

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第11张图片

3.3、在protoc3版本中,测试paced功能?

3.3.1、当packed采用默认值的情况,即不显示设置packed值

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第12张图片

3.3.2、当显示设置packed为true时的情况

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第13张图片

3.3.3、当显示设置packed为false时的情况

Protobuf 介绍与实战52:在proto文件中,数据类型为string,bytes,embedded messages,packed repeated fields时,变量值采用何种方式编码_第14张图片

3.4、总结:

  • 在proto2版本中,packed功能,默认没有启用。
  • 在proto3版本中,packed功能,默认是启用的,用户不需要做设置。(用户如果想禁止使用的话,可以使用packed=false)

从上面的测试用例来看,

  • 如果使用的是proto2版本的话,使用repeated关键字修饰时,最好也添加上packed=true,从而进一步提高编码效率
  • 如果使用的是proto3版本的话,用户不用关心packed,就当没有这个关键字就行了。

下一篇文章

  在proto文件中,数据类型为fixed64,sfixed64,double时,变量值采用何种方式编码(64-bit)

你可能感兴趣的:(grpc-go,golang,protobuf,docker,kubernetes)