【问题标题】:Protobuf-net Protogen generates DataFormat.TwosComplement for int32Protobuf-net Protogen 为 int32 生成 DataFormat.TwosComplement
【发布时间】:2012-09-09 10:07:52
【问题描述】:

我正在使用 protobuf-net r580 中包含的 Protogen 来编译以下 .proto 文件:

message TestMessage2 {
  required int32 someint = 1; 
}

我发现生成的代码使用 TwosComplement 线格式很奇怪:

Private _someint As Integer
<Global.ProtoBuf.ProtoMember(1, IsRequired:=True, Name:="someint", DataFormat:=Global.ProtoBuf.DataFormat.TwosComplement)> _
Public Property someint As Integer

而不是更优化的默认 varint 类型。这是预期的行为吗?

【问题讨论】:

  • 正如 Jon 所指出的,.proto 模式中的“int32”是必需才能使用常规(非锯齿形)varint 编码,这正是这里发生的情况。如果您想要 zigzag varint 编码,请指定“sint32”。无论哪种方式,这都是一个变种。唯一的问题是:它是曲折的。

标签: protobuf-net protogen


【解决方案1】:

这是与“核心”protobuf 文档相匹配的行为。来自"More Value Types" 部分:

有符号整数

正如您在上一节中看到的,与线类型 0 关联的所有协议缓冲区类型都被编码为 varint。但是,在编码负数时,带符号的 int 类型(sint32 和 sint64)与“标准”int 类型(int32 和 int64)之间存在重要区别。如果您使用 int32 或 int64 作为负数的类型,则生成的 varint 始终为 10 个字节长——实际上,它被视为一个非常大的无符号整数。如果您使用其中一种有符号类型,则生成的 varint 使用 ZigZag 编码,这样效率更高。

“默认的 varint 类型”是低效线格式,用于可能为负数的值。

根据文档,使用 sint32 来使用 ZigZag 编码。

基本上,在我看来 protobuf-net 的行为绝对正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多