听起来像使用自定义压缩机制,利用数据可能非常有效。
首先,使用short[]
(16位数据类型),而不是一个int[]
将减半(!)发送的数据量,你可以做到这一点,因为数字是很容易-2^15
(-32768)和2^15-1
(32767)之间。这是很容易实现的。其次,您可以使用类似于游程编码的方案:正数表示字面数,而负数表示多个零(取绝对值后)。例如
[10, 40, 0, 0, 0, 30, 0, 100, 0, 0, 0, 0] <=> [10, 40, -3, 30, -1, 100, -4]
这是很难实现的非常最坏的情况下,仅仅代short
为int
,但会提供〜80%的压缩(1000号,100非零,其中没有一个是连续的)。
我只是做了一些模拟来计算压缩比率。我测试了上面描述的方法,以及Louis Wasserman和sbridges提出的方法。两者表现都非常好。
假设阵列的长度和非零数的数目都是均匀的边界之间,这两种方法节省约5400 int
S(或short
多个)上平均具有约2.5%的原始压缩尺寸!运行长度编码方法似乎可以节省大约1个额外的int
(或平均压缩大小小0.03%),即基本没有区别,所以应该使用最容易实现的方法。以下是50000个随机样本的压缩率的直方图(它们非常相似!)。
摘要:使用short
!而非int
S和压缩方法之一,您将能够将数据压缩到原来大小的1%!
对于模拟,我用下述R脚本:
SIZE <- 50000
lengths <- sample(1000:10000, SIZE, replace=T)
nonzeros <- sample(1:100, SIZE, replace=T)
f.rle <- function(len, nonzero) {
indexes <- sort(c(0,sample(1:len, nonzero, F)))
steps <- diff(indexes)
sum(steps > 1) + nonzero # one short per run of zeros, and one per zero
}
f.index <- function(len, nonzero) {
nonzero * 2
}
# using the [value, -1 * number of zeros,...] method
rle.comprs <- mapply(f.rle, lengths, nonzeros)
print(mean(lengths - rle.comprs)) # average number of shorts saved
rle.ratios <- rle.comprs/lengths * 100
print(mean(rle.ratios)) # average compression ratio
# using the [(index, value),...] method
index.comprs <- mapply(f.index, lengths, nonzeros)
print(mean(lengths - index.comprs)) # average number of shorts saved
index.ratios <- index.comprs/lengths * 100
print(mean(index.ratios)) # average compression ratio
par(mfrow=c(2,1))
hist(rle.ratios, breaks=100, freq=F, xlab="Compression ratio (%)", main="Run length encoding")
hist(index.ratios, breaks=100, freq=F, xlab="Compression ratio (%)", main="Store indices")
它是什么样的数据?文本? – huon 2012-04-29 04:26:11
@dbaupp很好的问题,抱歉不提。我更新了问题以包含它。 – 2012-04-29 04:31:05
你是否说过当你尝试gzip时看到了改进,但即使在它的cpu密集度最高的设置下,你的cpu时间也过剩了? – joshp 2012-04-29 04:31:07