【发布时间】:2011-05-02 14:51:45
【问题描述】:
我有一个案例需要压缩很多通常很小的值。因此我用可变长度字节编码(ULEB128,具体来说)压缩它们:
size_t
compress_unsigned_int(unsigned int n, char* data)
{
size_t size = 0;
while (n > 127)
{
++size;
*data++ = (n & 127)|128;
n >>= 7;
}
*data++ = n;
return ++size;
}
有没有更有效的方法来做到这一点(也许使用 SSE)?
编辑:压缩后,结果存储到data,占用size字节。然后,在下一个 unsigned int 上调用压缩函数。
【问题讨论】:
-
技术上这称为 ULEB128 编码。
-
我认为您应该添加一些关于
n变量类型的内容,因为它的确切范围限制可能会影响使用 SSE 和类似扩展的可能性。 -
您可能想查看其他编码方法。在 protobuf 的开发过程中,Google 执行了各种基准测试,他们发现前导位指标很慢,因为您对每个数据字节都有一个测试(基本上是不可预测的)。发现将结构分成两部分:首先指示每个“包”的长度,然后推挤包,速度更快。
-
您可以尝试将循环转换为 bitscan(n)/7 上的开关。此外,不要进行 1 字节存储,而是使用临时变量,然后将其 memcpy()
-
@Alexandre:我正在阅读 Jeffrey Dean,他是 Google 的开发人员之一 (research.google.com/people/jeff/index.html)。我再也找不到 protobuf 的二进制格式规范了。我记得他们使用了 4 种不同的压缩技术,具体取决于消息的部分。 (我认为有些人使用 ULEB128,尽管他们称之为 varint)。