数据传输的痛点和需求
- 数据交换网络通信的场景中,存在的痛点在于 数据的体积大小 ,以及传输完成后 解析数据的速度 。
protobuf 的效率
- protobuf 序列化后是json的10分之一,xml的20分之一,但是性能是它们的5~100倍。
- 我们横向对比下两种格式
- JSON 格式
{ "id":1, "name":"czh", "hobby":"coding" "introduction":"hello world" }
- XML格式
<id>1<id> <name>czh<name> <hobby>coding<hobby> <introduction>hello world</introduction>
protobuf 传输体积小的原因
-
IDL(Interface Description Languange)来表示要传输的数据
message Person { required int32 id = 1; required string name = 2; required string hobby = 3; required string introduction = 4; }
-
protobuf 传输体积比XML和JSON要小在于没有将 id、name、hobby、introduction 放到要传输的数据里面。
| 1 | czh | coding | hello world |
| ---- | ---- | ------ | ----------- | -
通信的两方会同时维护这个文件
-
这样又会引出一个问题 ---> 后三个字符串分别属于哪一个字段?
- 用 tag 对每一个字段进行区分
|TAG 1|TAG chz|TAG coding|TAG hello world|
|-------|-------|-------|-------| - makeTag 函数
static int makeTag(final int fieldNumber, final int wireType){ return (fieldNumber << 3) | wireType; }
该函数会传入一个fieldNumber,和一个 wireType
返回值是将 fieldNumber 左移三位,并且 或上 wireType
|Type|Meaning|Used For|
|-------|-------|-------|
|0|Varint|int32,int64,uint32,uint64,sint32,sint64,bool,enum|
|1|64-bit|fixed64,sfixed64,double|
|2|Length=delimited|string,bytes,embedded messages,packed repeated fields
|3|Start group|groups(deprecated)|
|4|End group| groups(deprecated)|
|5|32-bit| fixed32,sfixed32,float|- 上表是 wireType的数据范围。
Protobuf 支持 0~5 的数据,用二进制表示就是 000~101
fieldNumber 左移空出来的三位可以用 wireType填补。
- 上表是 wireType的数据范围。
- 用 tag 对每一个字段进行区分