java – 压缩数字数组
我有一个大数组(~400.000.000个条目),整数为{0,1,…,8}.
所以每个条目我需要4位.大约200 MB. 目前我使用字节数组并在每个条目中保存2个数字. 我想知道,如果有一个好的方法,压缩这个数组.我做了一个快速研究,发现了像Huffmann或LZW这样的算法.但这些算法都用于压缩数据,将压缩数据发送给某人并解压缩. 我只想拥有一个具有较少内存空间的表,因此我可以将其加载到RAM中. 200MB的桌子很容易适合,但我正在考虑更大的桌子. 重要的是,我仍然能够确定某些位置的值. 有小费吗? 更多的信息: 我只需要一个快速的getValue(idx)功能,setValue(idx,value)并不重要. 解决方法
这取决于您的数据的样子.是否有重复的条目,或者它们只是缓慢地改变,或者是什么?
如果是这样,您可以尝试压缩数据块并在需要时解压缩.块越大,可以节省的内存越多,速度越差.恕我直言没什么好处.您还可以将数据压缩并解压缩到内存中. 否则,即,如果没有规律性,每个条目至少需要log(9)/ log(2)= 3.17位,没有什么可以改善它. 通过将5个数字打包成一个短数,你可以非常接近这个值.如9 ** 5 = 59049< 65536 = 2 ** 16,几乎完美.你需要每位数3.2位,没有大赢.通过该公式给出五个数字的包装 a + 9 * (b + 9 * (c + 9 * (d + 9 * e))) 并且通过预先计算的表来解压缩是微不足道的. 问题更新后更新
事实上平均有大约2.14个连续数字是相同的可能导致一些压缩,但在这种情况下它没有说什么.几乎只有五个和六个,所以似乎暗示了遇到两个相等的连续数字. 鉴于这一事实,您可以忘记我的上述优化.由于您可以单独处理单个零,因此实际上只有8个值.因此,每个值只需要3位,零点需要一个索引. 您甚至可以为低于4或高于7的所有值创建HashMap,存储1 154 10373 385990 80个条目,每个值仅使用2位.但这还远非理想. 假设没有规律性,你需要每个值1.44位,因为这是entropy.你可以浏览所有5元组,计算它们的直方图,并使用1个字节来编码255个最频繁的元组.所有剩余的元组都将映射到第256个值,告诉您必须在HashMap中查找稀有元组值. 一些评价 我很好奇它是否可行.将5个数字打包成一个字节需要85996340个字节.有近500万个元组不适合,所以我的想法是为它们使用哈希映射.假设重新开始而不是链接它是有意义的保持它可能50%满,所以我们需要1000万条目.假设TIntShortHashMap(将索引映射到元组),每个条目占用6个字节,导致60 MB.太糟糕了. 在一个字节中只包含4个数字,消耗107495425个字节,并留下159531个不适合的元组.这看起来更好,但是,我确信更密集的包装可以得到很大改善. 由这个小program产生的结果: *** Packing 5 numbers in a byte. *** Normal packed size: 85996340. Number of tuples in need of special handling: 4813535. *** Packing 4 numbers in a byte. *** Normal packed size: 107495425. Number of tuples in need of special handling: 159531. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |