存储大量的32位整数值,按升序排序,仅存储唯一值,以便顺序读取。原始文件很大,无法放入RAM,逐块读取。到目前为止,我只是将它们保存为二进制文件,每个值4个字节。
随着系统的发展,需要优化存储/备份空间,我发现考虑到这些数据的排序,这种数据的有效压缩潜力巨大。
我想出的是存储初始值,然后存储增量,随着集合中值的增加,这些增量往往是较小的值。将它们的大小舍入为完整字节,我建议每个增量只留下有意义的字节,因此每个增量可以有1-2-3个字节而不是4个。并且为了表示使用的字节数,我每个增量使用头2位。
该流看起来像:
01010101 01010101 01010101 01010101 - initial value
Four increments block start
10110101 - b bytes used: four 2-bit pairs
(10 11 01 01 = 2, 3, 1, 1)
01010101 01010101 - inc
01010101 01010101 01010101 - inc
01010101 - inc
01010101 - inc
Four increments block start
11011101 - b (11 01 11 01 = 3, 1, 3, 1)
01010101 01010101 01010101 - inc
01010101 - inc
01010101 01010101 01010101 - inc
01010101 - inc
...
我想在这里发明一个轮子吗?流压缩在这里可以更有效,可以在相当小的块上运行吗?
答案 0 :(得分:1)
这称为variable-length integers or variable-length quantities。根据差异的分布,为应用程序提供一种可能更有效的方法,并且更快,同时避免处理比特流,是使用剩余的7位来编码每个字节的高位整数的末尾。整数位的每个字节。因此,例如,您可以将高位1指示整数的结尾,其中整数位首先存储最高有效位。然后将0..127存储为字节0x80..0xff。如果第一个字节是0x01..0x7f,那么你得到数字的高7位,然后转到下一个7位的下一个字节,直到你得到一个高位。
这也具有不允许初始字节0x00的属性,因此您可以使用它来指示流的结束。
例如,如果128..255范围内的差异很常见,那么您的方案可能会更有效。在这种情况下,您的方案使用10位,其中上述使用16位。另一方面,如果0..127范围内的差异是最常见的,上面可能是最好的,因为它将那些编码为8位,你的使用十。
完成编码后,您可以通过应用标准压缩例程(例如zlib)进一步压缩。