为什么protobuf在序列化数据中包含数据类型?
Why does protobuf include datatype in the serialized data?
Protobuf 在序列化数据中包含数据类型(Thrift 也这样做)。但是,读取数据的应用程序应该能够从模式中获取此信息。
我能想到的唯一可以从这种设计中受益的场景是用户完全丢失了架构信息。比如说,他们的机器完全坏了,源代码和模式没有存储在其他任何地方。他们正试图从需要自包含反序列化数据的硬盘驱动器中恢复数据。但我怀疑这种设计是否涵盖了这种极其罕见的情况。
此外,在序列化中排除数据类型绝对可以在一定程度上节省 space 而不会损害运行时性能。有什么想法吗?
Protobuf includes datatype in the serialized data
通常不会,不会。它唯一一次这样做是在您使用 Any
类型时(当它需要它知道您存储了哪个 message
时),或者如果您使用的库具有一些非标准支持类型元数据。它绝对不会正常存储有关类型的任何信息 - 仅存储字段编号和电线类型。我怀疑您对正在查看的数据有一些误解。
如果你意思是电线类型;它需要能够跳过(或逐字存储,用于往返)它不知道的字段(那些在生成它的架构中 不是 )。连线类型 没有 足够的信息来理解字段内容 - 如果没有架构,它会非常模糊 - 例如 "length prefixed" 可以表示至少 4 种不同的数据类型。最终,它是 3 位,并与 和 字段编号一起打包;大多数时候(好吧,七分之四,包括字段 1-15)它甚至不需要额外的字节。
为了正确看待这一点,在 xml 中,查找当前值结束的规则是:
- 如果它是一个属性,寻找结束
"
- 如果它是一个元素,寻找结束符
</theElementName>
(考虑到任何嵌套)
这里的电线类型定义相同的东西:
- 对于 varint:读取(并包括)下一个未设置高位的字节(预期最多 10 个)
- 对于 64 位:读取 8 个字节
- 对于 32 位:读取 4 个字节
- 对于定界长度:读取一个 varint,然后读取那么多字节
- 对于起始组:读取到匹配的结束组(考虑到任何嵌套)
所以这就是告诉你什么时候停止,如果你因为没有预料到那个字段而不知道的话。
Protobuf 在序列化数据中包含数据类型(Thrift 也这样做)。但是,读取数据的应用程序应该能够从模式中获取此信息。
我能想到的唯一可以从这种设计中受益的场景是用户完全丢失了架构信息。比如说,他们的机器完全坏了,源代码和模式没有存储在其他任何地方。他们正试图从需要自包含反序列化数据的硬盘驱动器中恢复数据。但我怀疑这种设计是否涵盖了这种极其罕见的情况。
此外,在序列化中排除数据类型绝对可以在一定程度上节省 space 而不会损害运行时性能。有什么想法吗?
Protobuf includes datatype in the serialized data
通常不会,不会。它唯一一次这样做是在您使用 Any
类型时(当它需要它知道您存储了哪个 message
时),或者如果您使用的库具有一些非标准支持类型元数据。它绝对不会正常存储有关类型的任何信息 - 仅存储字段编号和电线类型。我怀疑您对正在查看的数据有一些误解。
如果你意思是电线类型;它需要能够跳过(或逐字存储,用于往返)它不知道的字段(那些在生成它的架构中 不是 )。连线类型 没有 足够的信息来理解字段内容 - 如果没有架构,它会非常模糊 - 例如 "length prefixed" 可以表示至少 4 种不同的数据类型。最终,它是 3 位,并与 和 字段编号一起打包;大多数时候(好吧,七分之四,包括字段 1-15)它甚至不需要额外的字节。
为了正确看待这一点,在 xml 中,查找当前值结束的规则是:
- 如果它是一个属性,寻找结束
"
- 如果它是一个元素,寻找结束符
</theElementName>
(考虑到任何嵌套)
这里的电线类型定义相同的东西:
- 对于 varint:读取(并包括)下一个未设置高位的字节(预期最多 10 个)
- 对于 64 位:读取 8 个字节
- 对于 32 位:读取 4 个字节
- 对于定界长度:读取一个 varint,然后读取那么多字节
- 对于起始组:读取到匹配的结束组(考虑到任何嵌套)
所以这就是告诉你什么时候停止,如果你因为没有预料到那个字段而不知道的话。