10

在 Java 中,我想将 (>10'000) 个长度为 32 的布尔值数组 (boolean[]) 存储到磁盘上,稍后再读取它们以进行进一步的计算和比较。

由于单个数组的长度为 32,我想知道将其存储为整数值是否有意义以加快读写速度(在 32 位机器上)。你会建议使用 BitSet 然后转换为 int 吗?或者甚至忘记 int 并使用字节?

4

2 回答 2

11

对于二进制存储,使用intand 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; 
  }
} 
于 2012-06-16T10:40:04.877 回答
1

我的强烈印象是,您为打包布尔值而进行的任何压缩都会增加读取和写入时间。(我的错误,我显然错过了我的药物)。您宁愿在所涉及的存储方面获得收益。

在您的业务逻辑方面,BitSet 是一个明智的选择。它在内部存储一个 long,您可以将其转换为 int。但是,由于 BitSet 足够谨慎,不会向您显示其私有信息,因此您需要按顺序获取每个位索引。这意味着我想转换为 int 而不是直接使用字节并没有真正的优势。

因此,Stefan Haustein 的自己滚动解决方案(根据需要扩展以模仿 BitSet)更适合您的存储需求,因为您不会产生任何不必要的开销。

于 2012-06-16T10:40:13.787 回答