protobuf字段排序是否会影响序列化后的on-the-wire大小?
问题结论
- 首先要明确两个易混淆概念的影响:
.proto文件中字段的书写先后顺序:完全不影响序列化后的on-the-wire体积,也不影响序列化兼容性,Protobuf规范允许序列化时按任意顺序输出字段,解析端均可正常识别。- 字段分配的字段号数值(即每个字段后
= N的N值):可能影响序列化体积,因为每个字段的Key由(字段号 << 3) | wire类型计算得到,Key采用varint编码,数值越小的字段号对应的Key占用字节数越少。
普通字段场景验证
你举的两组普通字段定义示例中,使用的字段号均为1和2,对应的Key均为1字节(varint编码小于128的数值仅占1字节),因此构造Message {x = 1, y = "foo"}实例时,两种定义的序列化体积完全一致,没有差异。
只有当字段号≥128时,对应的Key会占用2字节;≥16384则占用3字节,以此类推,这种场景下给高频使用的字段分配更小的字段号才会降低序列化体积。
repeated字段场景规则
repeated字段遵循完全相同的规则,仅在两种场景下有差异:
- 开启packed编码(proto3中数字类型repeated字段默认开启):整个repeated数组仅编码一个Key,字段号大小对体积的影响和普通字段一致。
- 关闭packed编码:repeated的每个元素都会单独编码一个Key,字段号大小对体积的影响会按元素个数放大,这种场景下给repeated字段分配更小的字段号收益更高。
你举的两组repeated字段示例中,字段号同样为1和2,Key均占1字节,因此两种定义的序列化体积没有差异,不存在把哪类字段放前面更省空间的区别。
内容的提问来源于stack exchange,提问作者akshayc
相关产品推荐
相关产品推荐

