我已经阅读了 谷歌协议的缓冲区 最近,它允许对各种各样的标值的类型中使用的信息。

根据 他们的文件, 有三种类型的变长整原始 int32, uint32, , sint32.在他们的文件,他们注意到, int32 是"效率低下编码的负面的数字–如果你的领域有可能具有负面价值观,使用 sint32 来代替。" 但是,如果你有一个领域,没有负面的数字,我认为uint32将是一个更好的类比 int32 不管怎么说的(由于额外的位和减少CPU成本处理的负面的数字)。

因此,当会 int32 是一个很好的标使用?是的文件意味着,这是效率最高的,只有当你很少获得负数字?或是它始终最好使用 sint32uint32, 根据字段的内容?

(同样的问题适用于64位的版本的这些标量,以及: int64, uint64, , sint64;但是我离开他们出的问题说明的可读性的缘故。)

有帮助吗?

解决方案

我不熟悉的与谷歌协议的缓冲器,但是我解释的文件是:

  • 使用 uint32 如果值不可能是负面的
  • 使用 sint32 如果价值是相当多的可能是否定的,因为没有(对于一些模糊的定义"作为可能是")
  • 使用 int32 如果值可能是负面的,但是这是不太可能比值是正面的(例如,如果应用有时候使用-1至表示错误或"未知"的价值,这是一种相对少见的情况)

这是什么医生必须说,有关的编码(http://code.google.com/apis/protocolbuffers/docs/encoding.html#types):

还有一个重要的差异之间签署int类型(sint32sint64)和"标准"int类型(int32int64)当涉及到编码负数。如果你使用 int32int64 作为类型为一个负数,得到的 varint 总是十字节长是,有效地处理像是一个很大的未签名的整数。如果您使用的签名类型,得到的 varint 用锯齿形编码,这是更有效率。

锯齿形编码的地图签署整数未签署整数,所以这一数字与一个小小的绝对值(例如,-1)有一个小的 varint 编码的价值。它这样做的方式"之牛头犬"来回通过积极和消极的整数,因此,-1编码为1,1个编码为2,-2编码为3,等等...

因此它看起来像甚至如果您使用的负面的数字是罕见的,只要幅度的数字(包括非负数)你们是通过在该议定书是对较小的一面,你可能会更好利用 sint32.如果你不确定、分析将是在订单。

其他提示

很少有很好的理由永远使用int *,而不是SINT *。这些额外类型的存在是最有可能的历史,向后兼容的原因,这协议缓冲器试图甚至跨越其自己的协议版本保持。

我最好的猜测是,在最早版本它们默默地在2的补码表示,这需要的9个字节(不计算额外的类型字节)的最大尺寸的varint编码进行编码负整数。然后,他们被困住与编码以免打破旧代码,并已经用它的序列化。因此,他们需要添加一个新的编码类型,圣马丁*,以获取负数更好的可变大小的编码,而不是破坏现有的代码。如何设计者没有意识到从一开始就这个问题是完全超越我。

在varint编码(无类型规范,这需要更多的字节)所用的以下的字节数编码的无符号整数值:

[0,2 ^ 7):一个字节

[2 ^ 7,2 ^ 14):两个字节

[2 ^ 14,2 ^ 21):三个字节

[2 ^ 21,2 ^ 28):四个字节

[2 ^ 28,2 ^ 35):五个字节

[2 ^ 35,2 ^ 42):六个字节

[2 ^ 42,2 ^ 49):7个字节

[2 ^ 49,2 ^ 56):八个字节

[2 ^ 56,2 ^ 64):9个字节

如果你想小幅度负整数编码同样紧凑,那么你将需要“占用”一位指示标志。您可以通过一个明确的标志位(在一些保留的位置)和幅度表示这样做。或者,你可以做之字形编码,由1位左移的幅度和负数减去1,有效地做同样的事(这样至少显著位指示符号:唇上都是非负的,赔率为负)。

无论哪种方式,在切点是阳性整数需要更多的空间现在配备的一个因子2较早:

[0,2 ^ 6):一个字节

[2 ^ 6,2 ^ 13):两个字节

[2 ^ 13,2 ^ 20):三个字节

[2 ^ 20,2 ^ 27):四个字节

[2 ^ 27,2 ^ 34):五个字节

[2 ^ 34,2 ^ 41):六个字节

[2 ^ 41,2 ^ 48):7个字节

[2 ^ 48,2 ^ 55):八个字节

[2 ^ 55,2 ^ 63):9个字节

要做出使用int *在SINT *的情况下,负号必须是极为罕见,但也是可行的,和/或你希望编码最常见正值将不得不下降对周围的切过的一个( - 2 ^ 6与2 ^ 7通向2×编码大小例如)

,导致在SINT较大编码*,而不是为int *分

基本上,如果你将有一个数字,其中一些可能是负的,则默认情况下使用烧结靶*而不是INT *。 INT *将很少优于通常甚至不会是值得的额外以为你要对判断是否值得与否恕我直言奉献。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top