【发布时间】:2021-08-22 15:20:40
【问题描述】:
问题是关于 protobuf,但首先我想从 flatbuffers 中解释类似的概念:
我知道在 flatbuffers 中我可以创建具有如下标量类型的 Point2d 结构:
struct Point2d {
x: double;
y: double;
}
table PointCloud {
point_array: [Point2d] (required);
}
这里的 struct 牺牲了模式演变,我可以忍受这一点,但作为回报,我可以拥有具有数百万个元素的此类点数组,开销几乎为 0,每个点结构(16 字节长)将是一个接一个地写入缓冲区,所以 2 个点需要 32 个字节,4 个点需要 64 个字节,等等。
我是 protobuf 世界的新手,但似乎 protobuf 总是 将带有字段 ID 的 varint 写入输出流,即使“消息”重复并包含标量类型也是如此。因此,对于每个重复的 point2d(16 个字节),我们有 2 个额外的 varint 字节,它们在“数组”中完全没用。
我说的对吗?它是否会在 point_array 中每个重复点的每个 x 和 y 字段之前实际写入 varint 字节? protobuf 中是否有替代 flatbuffer struct 的方法?
更具体地说,我包含类似于 flatbuffer 文件的 proto:
message Point2d {
double x = 1;
double y = 2;
}
message PointCloud {
// Is protobuf serializing 2 varints with each Point2d in this repeated field?
repeated Point2d point_array = 1;
}
【问题讨论】:
-
另外两个 varint 并不是没用的。您将如何支持升级到 3d 矢量(x、y、z)?你怎么知道 3 point2d 的数组和 2 point3d 的数组之间的区别?具有小值的 varint 使用单个字节进行序列化。与您为兼容性方案支付的价格相比,开销很小。没有什么能阻止您使用双精度数组和一个指示点大小的单个 int 发出消息
-
1 - 我永远不需要将 2d 点升级到 3d 点。 2 - point_array 有 field-id,并且这个 id 已经与类型相关联(它是 2d 点的数组)。
标签: protocol-buffers flatbuffers