我正在研究的项目,我有一系列数字(大约20亿)。每个数字是4个字节并且是唯一的。数字已排序。我的目标是尽可能以未压缩的格式将它们读入RAM。它并不关心硬盘空间。
如果我将它们保存为未压缩的,我需要20亿* 4字节= 8GB。这将花费大约100秒来阅读。我可以将数据存储为一系列位,这将需要20亿/ 8 = 250MB。这将花费大约3秒钟来阅读。
我需要使用普通硬盘以0.1-0.5秒(如果可能)读取和解压缩它们。我不关心压缩数据需要多长时间,但我真正关心解压缩它需要多长时间,我需要在几毫秒内完成。
数字的随机性尚不清楚。
问题:什么样的压缩算法可以使用i3-i5 CPU将数据压缩到大约20-30MB,解压缩时间为100-200毫秒?
编辑:序列中的最大数量为20亿。这就是我将它存储在250MB大小的阵列上的原因。序列的大小并不总是20亿。它可以包含1到2.000.000.000个数字。
答案 0 :(得分:0)
以下是两种可能的方法:
提问者建议将数字序列存储为位串。例如:如果数字 i 在序列中,则位串的 i th 位设置为1,否则为&#39 ;零。首先要尝试的是将标准压缩算法应用于此位字符串,看看会发生什么。
从问题的措辞来看,似乎我们可以将序列中的数字视为4字节的整数。因此,待存储的序列表示可能的2 32 整数中的2 * 10 9 。这意味着任何两个连续数字之间的平均差异不能超过~2.147 = 2 32 /(2 * 10 9 )。所以,也许计算差异的序列并尝试压缩它。由于我预计连续差异的很大一部分将是1和2,我怀疑这个序列可能是非常可压缩的。
答案 1 :(得分:0)
将它存储为一系列位的方法可以正常工作,但是每个四字节整数需要512 MiB,而不是250 MB。
delta编码方案对于密度较小的集合会更好,但不适用于此(如原始问题中所述,它是随机选择的一半可能的32位整数)。这里delta 1将出现大约一半的时间,delta 2将出现四分之一的时间,依此类推。这将导致2 30 + 2x2 29 + 3x2 28 + ... = 2 32 位。与位向量方法相同。
最优压缩方案将2 32 的对数基数2选择2 31 位。这也证明是2 32 位。 (实际上,2 32 -16位,因此可以在40亿中保存高达16位。)
因此位向量与它一样好。
更新的问题完全不同。现在问题的范围很广,从一个到31个整数的一个到一个整数,并询问如何将其压缩到20 MiB到30 MiB。
这些压缩大小限制了集合的大小。给定集合的大小,可以简单地计算该大小的31位整数的可能子集的数量,让它称之为 n 。可能的子集数量为2 31 选择 n 。 "choose" is the binomial coefficient。该数量的可能子集的对数基数2是特定子集的压缩大小的理论最小值,假设所有这些子集都具有相同的可能性。
所以现在我们可以计算出可以压缩到20 MiB到30 MiB的最大可能尺寸。结果是21到3400万。您还可以压缩大小为2 31 减去21到3400万的子集,因为您可以将这些子集视为由缺少的值识别而不是存在的值。介于两者之间的任何东西都需要超过30 MiB来表示理论上最佳的压缩方案。更新后的问题要求提供各种可能的子集,其中绝大多数都在3400万到21亿之间。
所以,底线,不可能将所描述的序列压缩到更新问题中指定的任何位置。