在 protobuf 中使用 int32 的原因

Mar*_*n G 4 c++ protocol-buffers

在 gpb proto2 标量类型的描述中(https://developers.google.com/protocol-buffers/docs/proto#scalar)它说:

\n\n
\n
    \n
  • 整型32

    \n\n

    使用可变长度编码。编码负\n 数字 \xe2\x80\x93 效率较低,如果您的字段可能有负值,请改用 sint32\n。

  • \n
  • sint32

    \n\n

    使用可变长度编码。有符号 int 值。这些比常规 int32 更有效地编码负数。

  • \n
\n
\n\n

对于正值,sint32 与 int32 一样有效吗?

\n\n

换句话说,有什么理由使用int32吗?

\n\n

如果使用什么语言很重要,我只对 C++ 感兴趣。

\n

eph*_*ent 5

https://developers.google.com/protocol-buffers/docs/encoding#signed-integers

有符号变体通过正值和负值交替进行编码。例如,

   value     int32    zigzag    sint32
          (binary)            (binary)
       0  00000000         0  00000000
      -1  11111111         1  00000001
          11111111
          11111111
          11111111
          00001111
       1  00000001         2  00000010
      -2  11111110         3  00000011
          11111111
          11111111
          11111111
          00001111
...
      63  00111111       126  01111110
     -64  11000000       127  01111111
          11111111
          11111111
          11111111
          00001111
      64  01000000       128  10000000
                              00000001
...
Run Code Online (Sandbox Code Playgroud)

sint平均而言,将正数编码为an 比编码为 需要多一位int

(展开并运行以下代码片段进行现场演示。)

   value     int32    zigzag    sint32
          (binary)            (binary)
       0  00000000         0  00000000
      -1  11111111         1  00000001
          11111111
          11111111
          11111111
          00001111
       1  00000001         2  00000010
      -2  11111110         3  00000011
          11111111
          11111111
          11111111
          00001111
...
      63  00111111       126  01111110
     -64  11000000       127  01111111
          11111111
          11111111
          11111111
          00001111
      64  01000000       128  10000000
                              00000001
...
Run Code Online (Sandbox Code Playgroud)
function encode_varint(number) {
  if (!number) return [0];
  var bytes = [];
  while (number) {
    var byte = number & 0x7F;
    number >>>= 7;
    if (number) byte |= 0x80;
    bytes.push(byte);
  }
  return bytes;
}
function format_bytes(bytes) {
  var output = '';
  for (var i = 0; i < bytes.length; i++) {
    if (i) output += ' ';
    output += bytes[i].toString(2).padStart(8, '0');
  }
  return output;
}
var valueElem = document.getElementById('value');
var int32Elem = document.getElementById('int32');
var sint32Elem = document.getElementById('sint32');
function update() {
  var value = parseInt(valueElem.value);
  var int32 = encode_varint(value);
  var sint32 = encode_varint(value << 1 ^ -(value < 0));
  int32Elem.value = format_bytes(int32);
  sint32Elem.value = format_bytes(sint32);
}
valueElem.addEventListener('change', update);
update();
Run Code Online (Sandbox Code Playgroud)
#varint {
  display: grid;
  grid-template-columns: max-content auto;
  grid-row-gap: 1ex;
  grid-column-gap: 1ch;
}
#varint label {
  text-align: right;
}
#varint input {
  font-family: monospace;
}
Run Code Online (Sandbox Code Playgroud)