在 Java 中,我想将 (>10'000) 个长度为 32 的布尔值数组 (boolean[]) 存储到磁盘上,稍后再读取它们以进行进一步的计算和比较。
由于单个数组的长度为 32,我想知道将其存储为整数值是否有意义以加快读写速度(在 32 位机器上)。你会建议使用 BitSet 然后转换为 int 吗?或者甚至忘记 int 并使用字节?
在 Java 中,我想将 (>10'000) 个长度为 32 的布尔值数组 (boolean[]) 存储到磁盘上,稍后再读取它们以进行进一步的计算和比较。
由于单个数组的长度为 32,我想知道将其存储为整数值是否有意义以加快读写速度(在 32 位机器上)。你会建议使用 BitSet 然后转换为 int 吗?或者甚至忘记 int 并使用字节?
对于二进制存储,使用int
and a DataOutputStream
(DataInputStream
用于读取)。
我认为 boolean 数组在 Java 内部存储为 byte 或 int 数组,因此您可能需要考虑避免开销并始终保持 int 编码,即根本不使用 boolean[]。
相反,有类似的东西
public class BooleanArray32 {
private int values;
public boolean get(int pos) {
return (values & (1 << pos)) != 0;
}
public void set(int pos, boolean value) {
int mask = 1 << pos;
values = (values & ~mask) | (value ? mask : 0);
}
public void write(DataOutputStream dos) throws IOException {
dos.writeInt(values);
}
public void read(DataInputStream dis) throws IOException {
values = dis.readInt();
}
public int compare(BooleanArray32 b2) {
return countBits(b2.values & values);
}
// From http://graphics.stanford.edu/~seander/bithacks.html
// Disclaimer: I did not fully double check whether this works for Java's signed ints
public static int countBits(int v) {
v = v - ((v >>> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); // temp
return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}
}
我的强烈印象是,您为打包布尔值而进行的任何压缩都会增加读取和写入时间。(我的错误,我显然错过了我的药物)。您宁愿在所涉及的存储方面获得收益。
在您的业务逻辑方面,BitSet 是一个明智的选择。它在内部存储一个 long,您可以将其转换为 int。但是,由于 BitSet 足够谨慎,不会向您显示其私有信息,因此您需要按顺序获取每个位索引。这意味着我想转换为 int 而不是直接使用字节并没有真正的优势。
因此,Stefan Haustein 的自己滚动解决方案(根据需要扩展以模仿 BitSet)更适合您的存储需求,因为您不会产生任何不必要的开销。