快速实时Java int[]压缩工具

快速实时Java int[]压缩工具,java,arrays,compression,int,Java,Arrays,Compression,Int,在Java中,在程序中的某个时刻,我必须在内存中处理千兆字节的int[]数组。它们经过排序,只包含表示文件行的自然编号(如1,2,3,4,…,最多为n)。Numbern是文件中的行数,最大值为100000。所以数组只是文件中所有行集合的子集。正如您所计算的,有数百万这样的子集,拥有其中的一些子集可能会有很大的权重。至于这些子集内的数据分布(我们现在称它们为数组),它是完全随机的:即一个长数组可以出现50000个数,而一个小数组只能出现1500个数;每个数组都包含不可预测的序列,因此它可以是[3,

在Java中,在程序中的某个时刻,我必须在内存中处理千兆字节的
int[]
数组。它们经过排序,只包含表示文件行的自然编号(如
1,2,3,4
,…,最多为
n
)。Number
n
是文件中的行数,最大值为
100000
。所以数组只是文件中所有行集合的子集。正如您所计算的,有数百万这样的子集,拥有其中的一些子集可能会有很大的权重。至于这些子集内的数据分布(我们现在称它们为数组),它是完全随机的:即一个长数组可以出现
50000
个数,而一个小数组只能出现
1500
个数;每个数组都包含不可预测的序列,因此它可以是
[3,10,11,12,13,14,15,135,136,…]
[2,3,746,7889,7892,80000,…]

因为我有很多要压缩/解压缩的数组,所以我希望在每次执行所花费的时间方面找到最快的解决方案。因此,开销应该尽可能小


你推荐什么图书馆?

也许这也能帮助你:

您需要对数组进行大量计算还是只读

编辑:

//如果空间比性能更重要,这可能会起作用:
//不是,在某些情况下,这可能是完全愚蠢的
//第一个元素应为false,因为它是0;)
布尔[]数字={false,true,true,false,false,true};

对于(int i=0;i我建议使用Google提供的端口,您可以无损地预处理数据以提高压缩效果。保持第一个值不变。使每个后续值与前一个值之间的差值减一。您可以确保这些差值不是负的。现在将每个整数编码为变量长度使用字节序列的第个整数。例如,解码时,0..127是一个字节。如果设置了第一个字节的高位(128..255),然后将低七位作为整数的低七位,并获取下一个字节。如果高位为零,则使用整个字节作为下八个更高的有效位,如果高位为1,则仅使用低七位。继续操作,直到到达高位等于零的字节,这表示整数结束

现在,您已经将整数编码为字节序列,可能比将每个原始整数编码为(比如)四个或八个字节要短一些。此外,您现在可以应用任何适用于字节序列的标准压缩技术,并可能从中获得一些收益。例如,如果序列行号如果你是普通人,那么你会得到一个高度可压缩的零字节字符串

要在牺牲压缩程度的同时获得最大的压缩和解压缩速度,请查看。如果您不需要那么快的速度,请查看,您可以根据压缩级别选择压缩速度和效果

例如,随机选择10000个字节中的1500个将导致1720个字节未压缩,1600个字节已压缩。随机选择100000个字节中的50000个将导致50000个字节未压缩,18600个字节已压缩。压缩是使用最快的zlib压缩(级别1)完成的

请注意,在后一种情况下,如果使用一半行号,则使用12500字节未压缩的位数组将更有效。在这种情况下,数据无法压缩,因为位映射看起来是随机的(一半位已设置,一半未设置).或多或少,例如25000或75000,都会产生可压缩的位图,都可以压缩到10500字节左右


压缩位图对于大约12500行及以上的行数较小,而压缩的差分变量整数对于少于大约12500行数较小。这一截止点是两种方法具有大约相同的12500字节未压缩大小的点。

根据您的描述,似乎很有可能ny数字出现多次。在这种情况下,运行长度编码(实现起来很简单)可能非常有效。不,数字不会重复,它们在数组中只出现一次。它们总是被排序吗?听起来像是
位集
最简单。
//If the space is more important than performance this might work:
//Not this might be totally stupid for some cases
// First element should be false since its the 0 ;)
boolean[] numbers = { false, true, true, true, false, false, true };

for (int i = 0; i <= numbers.length - 1; i++) {
    if (numbers[i]) {
    // or do some calculations on/with a copy of i
    System.out.println(i);
    }
}