为什么对b序列使用bzip2的压缩率如此跳跃?


15
library(ggplot2)

compress <- function(str) {
  length(memCompress(paste(rep("a", str), collapse=""), type="bzip2"))
  / nchar(paste(rep("a", str), collapse=""))
}

cr <- data.frame(i = 1:10000, r = sapply(1:10000, compress))

ggplot(cr[cr$i>=5000 & cr$i<=10000,], aes(x=i, y=r)) + geom_line()

在此处输入图片说明

压缩比从“ a”的37开始,达到39“ a” s的收支平衡(压缩比= 1)。图表开始时非常平稳,并且突然以98“ a”的速度渐渐前移,并从此逐渐变小。

局部低点和平滑部分似乎也很不稳定和随机。有人可以向我解释为什么bzip2在此示例中显示此行为吗?

Answers:


14

假设一个简单的压缩算法a通过存储(即一些固定的标头,字符串和重复次数。这是行程编码。那么对于某些常量,压缩文本的长度将接近位。相应的压缩比为。如果忽略局部起伏,则从远处看,这大致是曲线的形状。渐近地,压缩比为与n a + lg n标头“一种”ñañ一种+lgñ一种一种+lgññΘlgñp/ñp1(我尚未解决,但我怀疑还有其他因素在起作用,这些因素会使输出的大小在输入字符串的长度上超线性)。

lgñ位不是整数位,更不用说字节了:的大小必须至少取整为整数字节。这说明了第一个阈值效应:对于这种简单的压缩算法,您将观察到,当足够小时,输出的长度为,然后,然后,依此类推。因此,压缩率不是a平滑的曲线,但从跳跃到,然后,等等,这种效果几乎看不到在跳跃后的重新排列(但还有其他效果在起作用,这会使跳动有所不同)。ñ一种ña + 2 a一种+1一种+2 a+1一种ñ一个+2一种+1ñ一种+2ñ

由于压缩率太接近视觉观察长度的反比,因此这是我实现中的小长度数据(这可能取决于bzip2库的版本,因为有多种方法可以压缩某些输入)。第一列表示的数量a,第二列表示压缩输出的长度。

1–3       37
4–99      39
100–115   37
116–258   39
259–354   45
355       43
356       40
357–370   41
371–498   43
499–513   41
514–609   45
610       43
611       41
613–625   42
626–753   44
754–764   42
765       40
766–767   41
768       42
769–864   45
…

Bzip2比简单的行程编码更复杂。它以一系列步骤工作,第一步是行程编码步骤,但具有固定的大小限制。第一步如下:如果一个字节重复至少4次,则将第4个字节之后的字节替换为一个字节,该字节指示已擦除字节的重复计数。例如,aaaaaaa将转换为aaaa\d{3}(其中\d{003}字节值为3的字符);aaaa转换为aaaa\d{0},依此类推。由于只有256个不同的字节值,因此只能以这种方式对字节重复最多259次的序列进行编码。如果还有更多,则重新开始一个序列。此外,参考实现在252的重复计数处停止,该重复计数对256个字节的字符串进行编码。

此步骤说明了第一阈值和阈值258:对于压缩为37个字节,对于压缩为最大39个字节。引入重复计数会在后续步骤的输出中再增加2个字节,并且该额外字节能够表示所有重复计数,最多258个。在258个字节之后,还有第二个RLE字符串。第三个为514字节,第四个为769字节,依此类推。第二个之后的额外RLE字符串根本不会花费很多,因为该序列(假设是重复计数,我没有检查)本身是重复的,因此可以通过后续步骤进行压缩。 1Ñ3一种ñ1ñ34ñ258aaaa\d{252}\d{252}

为什么将阈值设置为258、516、769(没有设置为1024),1279,而不是256的精确倍数?我怀疑这是因为Burrows-Wheeler变换后跟前移可以通过将'一起移动来进行变换aaaa\374aa(第1步的输出,),以便可以将它们一起编码,但是我没有检查。ñ=258a

在处长度的减少很有趣。对于输入,第一个RLE步骤产生-但是字节值是97,因此这具有后续步骤进行压缩的更好潜力。我怀疑不仅对于而且对于周围的值,收缩效果都归因于增量编码步骤,该步骤使存储附近值的字节更容易。如果更改为(65),则会注意到较短的输出发生在。ñ=100一种101aaaa\d{97}aaaaaañ=101aA68ñ83

我对这个示例的分析还很详尽。要了解其他效果,您必须研究转换的其他步骤:我基本上是在9的第1步之后停下来的。我希望这可以使您了解为什么压缩率会变得不稳定并且不会单调变化。如果您真的想弄清楚每个细节,我建议您采用现有的实现,并使用调试器进行观察。

在大多数情况下,在设计压缩算法时,这种微小的变化并不是主要关注点:在许多常见情况下,例如通用或媒体压缩算法,只有几个字节的差异是无关紧要的。压缩试图在本地层面压缩每一点,并试图以一种经常失败而很少损失然后很少增加的方式来链接转换。但是,在某些情况下,例如为低带宽通信而设计的专用通信协议,每个比特都很重要。确切的输出长度很重要的另一种情况是对压缩的文本进行加密:当对手可以提交要压缩和加密的文本的一部分时,密文长度的变化可以将压缩和加密的文本的一部分显示为:对手; HTTPS上的CRIME 攻击

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.