[英]How to create efficient bit set structure for big data?
一种解决方案是使阵列远离堆。
您将需要阅读@PeterLawrey的相关问题的答案 。
总之,Java中的内存映射文件的性能非常好,并且避免了在堆上保留大量对象。
操作系统可能会限制单个内存映射区域的大小。 通过映射多个区域可以轻松解决此限制。 如果区域的大小固定,则可以使用对实体索引的简单二进制操作在内存映射文件列表中找到相应的内存映射区域。
您确定需要压缩吗? 压缩将以时间换取空间。 减少的I / O可能最终节省了您的时间,但也可能不会。 可以添加SSD吗?
如果您还没有尝试过内存映射文件,则从此开始。 我将仔细研究在Peter的《编年史》之上实现一些东西。
如果需要更高的速度,可以尝试并行执行二进制操作。
如果最终需要压缩,则可以始终在Chronicle的内存映射数组的顶部实现它。
从这里的评论中,我想补充您最初提出的问题:
BitSet
可能是我们可以使用的最好的 话虽如此,我的建议是实施一个专用的缓存解决方案,如果LRU是可接受的驱逐策略,则使用具有访问顺序的LinkedHashMap
,并在磁盘上为BitSetS
永久存储。
伪代码:
class BitSetHolder {
class BitSetCache extends LinkedHashMap<Integer, Bitset> {
BitSetCache() {
LinkedHashMap(size, loadfactor, true); // access order ...
}
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > BitSetHolder.this.size; //size is knows in BitSetHolder
}
}
BitSet get(int i) { // get from cache if not from disk
if (bitSetCache.containsKey(i) {
return bitSetCache.get(i);
}
// if not in cache, put it in cache
BitSet bitSet = readFromDisk();
bitSetCache.put(i, bitSet);
return bitSet();
}
}
那样 :
如果这是您要求的一种选择,我可以再发展一点。 无论如何,这适用于其他驱逐策略,因为LRU是LinkedHashMap
本机,所以它是最简单的。
最佳解决方案在很大程度上取决于数据的使用模式和结构。
如果您的数据具有超出原始位Blob的某种结构,则可以使用其他数据结构做得更好。 例如,可以使用DAG在空间和查找时间上非常有效地表示单词列表。
BitSet在内部表示为long [],这使其重构起来稍微困难一些。 如果您从openjdk中获取源代码,则需要对其进行重写,以使其在内部使用迭代器,并由文件或内存中压缩的blob作为后盾。 但是,您必须重写BitSet中的所有循环才能使用迭代器,因此不必完全实例化整个Blob。
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/BitSet.java
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.