Compression 对唯一数据流的压缩
我有很多整数数组。每一个都有几千个整数,每个整数通常与前面的整数相同,或者只相差一两位。我想缩小每个阵列,使其尽可能小,以减少磁盘IO Zlib将其缩小到原来大小的25%左右。这很好,但我不认为它的算法特别适合这个问题。是否有人知道一个压缩库或简单算法可以更好地处理这类信息Compression 对唯一数据流的压缩,compression,zlib,Compression,Zlib,我有很多整数数组。每一个都有几千个整数,每个整数通常与前面的整数相同,或者只相差一两位。我想缩小每个阵列,使其尽可能小,以减少磁盘IO Zlib将其缩小到原来大小的25%左右。这很好,但我不认为它的算法特别适合这个问题。是否有人知道一个压缩库或简单算法可以更好地处理这类信息 更新:zlib将其转换为一个xor增量数组后,会将其缩小到原始大小的20%左右 你试过bzip2吗? 对我来说,它总是比zlib更有效。你考虑过吗 或者试着这样做:不存储数字本身,而是存储数字之间的差异。1235变为101
更新:zlib将其转换为一个xor增量数组后,会将其缩小到原始大小的20%左右 你试过bzip2吗? 对我来说,它总是比zlib更有效。你考虑过吗 或者试着这样做:不存储数字本身,而是存储数字之间的差异。1235变为101012。现在,大多数需要编码的数字都非常小。要存储小整数,请使用8位整数,而不是在大多数平台上编码的32位整数。这是4的因子。如果您确实需要为更大的间隙做好准备,请指定8位整数的高位,表示“此数字还需要下一个8位” 根据您的数据,您可以将其与运行长度编码相结合,以获得更好的压缩比
这两个选项都不是特别难实现的,它们都运行得非常快,内存非常少(与bzip相反)。也许答案是以类似于bzip的方式预过滤阵列。下面是我脑海中的一些想法。我没有尝试过这些方法,但如果你想玩,它们可能会很有趣
您需要预处理数据——首先,可逆地将其转换为更适合后端数据压缩方法的某种形式。详细信息将取决于后端压缩方法,以及(更重要的是)所压缩数据的预期属性 在您的例子中,zlib是一种字节压缩方法,但您的数据是(32位?)整数。您不需要自己重新实现zlib,但您确实需要阅读它的工作原理,这样您就可以找出如何使用易于压缩的数据来表示它,或者它是否适合您的目的
Zlib实现了一种形式的Lempel-Ziv编码。JPG和许多其他人在后端使用哈夫曼编码。运行长度编码在许多特殊用途中很流行。等等……由于您关心的是减少磁盘IO,因此您需要独立压缩每个整数数组,而不参考其他整数数组 场景中的一种常见技术是存储差异,因为少量差异可以用短码字编码。听起来您需要为差异制定自己的编码方案,因为它们是多位差异,可能需要使用8位字节作为起点:
- 1位,表示后面是一个完整的新整数,或该字节编码了与上一个整数的差异
- 1位表示后面有更多字节,记录同一整数的更多单位差异
- 6位,记录要从上一个整数切换的位号
如果你也有很多完全不同的代码,这个方案可能不合适,因为它们现在每个需要5个字节,而不是4个。如果大多数整数真的与前面的相同,并且符号间的差异通常可以表示为单位翻转,这听起来像是异或的工作 采用如下输入流:
1101
1101
1110
1110
0110
和输出:
1101
0000
0010
0000
1000
一点伪代码
compressed[0] = uncompressed[0]
loop
compressed[i] = uncompressed[i-1] ^ uncompressed[i]
我们现在已经将大部分输出减少到0,即使更改了高位。您使用的任何其他工具中的RLE压缩都将有一天与此相关。它可以更好地处理32位整数,并且它仍然可以对流中出现的完全不同的整数进行编码。您省去了自己处理比特打包的麻烦,因为所有东西都是整数大小的数量
当您要解压缩时:
uncompressed[0] = compressed[0]
loop
uncompressed[i] = uncompressed[i-1] ^ compressed[i]
这也是一个简单的算法,运行速度非常非常快,因为它只是XOR