Protobuf中是否存在可替代FlatBuffers struct的低开销结构方案?
问题解答
问题1确认:你给出的默认proto定义确实存在额外varint开销
你提供的repeated Point2d写法下,序列化时每个Point2d元素除了16字节的x、y原始数据外,确实会产生额外的varint开销:
- 每个Point2d作为嵌套message,头部会有1字节的长度varint
- 内部的x、y字段各带1字节的「字段号+类型」varint前缀
单个Point2d的额外开销共3字节,和FlatBuffers的连续struct数组相比存储密度差距明显。
问题2:Protobuf存在低开销连续存储的替代方案
你可以用packed repeated标量数组实现和FlatBuffers struct数组接近的存储效率,对应proto可以改成如下写法:
// Protobuf 3版本写法,repeated数字类型默认开启packed message PointCloud { // 每两个元素依次对应一个Point2d的x、y坐标 repeated double point_coords = 1; } // Protobuf 2版本写法,需要手动指定packed选项 message PointCloud { repeated double point_coords = 1 [packed = true]; }
这种写法的序列化特性完全符合你的需求:
- 整个数组仅在最头部写入一次「字段号+类型+总长度」的varint前缀,总开销最多4-5字节,和数组长度无关
- 所有double值连续无间隔存储,16字节对应一个Point2d,和FlatBuffers struct数组的存储密度完全一致
- 取舍和FlatBuffers struct相同:牺牲了结构的语义封装和schema演进能力(如需新增z字段需要单独加新的repeated字段,不能直接修改原有结构),符合你提到的可接受范围。
内容的提问来源于stack exchange,提问作者Ibraim Ganiev
相关产品推荐
相关产品推荐

