Protocol Buffers 和 Avro 中 ZigZag 编码背后的原因是什么?

What's the reason behind ZigZag encoding in Protocol Buffers and Avro?

ZigZag 需要大量开销才能 write/read 数字。实际上,我很惊讶地发现它不仅按原样写入 int/long 值,而且还进行了很多额外的加扰。甚至还有一个循环: https://github.com/mardambey/mypipe/blob/master/avro/lang/java/avro/src/main/java/org/apache/avro/io/DirectBinaryEncoder.java#L90

我似乎无法在 Protocol Buffers 文档或 Avro 文档中找到,或者自己推理,这样的加扰数字有什么好处?为什么编码后正负数交替更好?

为什么它们不只是按照小端、大端、网络顺序编写,这样只需要将它们读入内存并可能反转位字节顺序?我们买什么用性能付费?

这是一个可变长度的7位编码。编码值的第一个字节将其高位设置为 0,后续字节将其设置为 1。解码器可以通过这种方式判断使用了多少字节来对值进行编码。无论机器架构如何,字节顺序始终是小端。

这是一种编码技巧,允许写入尽可能少的字节来对值进行编码。所以一个 8 字节的 long 值在 -64 和 63 之间只需要一个字节。这很常见,long 提供的范围在实践中很少使用。

设计目标是在没有 gzip 式压缩方法开销的情况下紧密打包数据。也用于。 en/decode 该值所需的处理器开销无关紧要。它已经比压缩方案低得多,只是 I/O 成本的一小部分。