【问题标题】:Very Compact Bitarray in JavaJava中非常紧凑的位数组
【发布时间】:2011-01-06 15:37:02
【问题描述】:

我正在寻找一种在 Java 中存储密集可变长度位数组的非常紧凑的方法。现在,我正在使用BitSet,但对于大小为 n 的位向量,它似乎平均使用 1.5*n 位 的存储空间。通常,这不是问题,但在这种情况下,存储的位数组是应用程序内存占用的重要部分。所以,让它们变小一点真的很有帮助。

BitSet 所需的空间似乎是由于用于支持数据结构的 long 数组在每次扩展以容纳更多位时往往会翻倍:

// BitSet's resizing code
private void ensureCapacity(int wordsRequired) {
  if (words.length < wordsRequired) {
    // Allocate larger of doubled size or required size
    int request = Math.max(2 * words.length, wordsRequired);
    words = Arrays.copyOf(words, request);
    sizeIsSticky = false;
  }
}

我可以编写自己的 BitSet 替代实现,更保守地扩展后端数据结构。但是,如果我不需要的话,我真的很讨厌复制标准类库中已经存在的功能。

【问题讨论】:

  • 我很难想象这会出现在标准 Java 库中。这不是它的设计目的。不过我打赌你可以找到第三方库。
  • 我认为在你的情况下自定义实现会更好。

标签: java memory bit-manipulation bitset bitarray


【解决方案1】:

如果您使用构造函数BitSet(int nbits) 创建BitSet,您可以指定容量。如果你猜错了容量,然后再过去,它将增加一倍。

BitSet 类确实有一个 trimToSize 私有方法,由 writeObject 和 clone() 调用。如果你克隆你的对象,或者序列化它,它会将它修剪到正确的长度(假设类通过 ensureCapacity 方法过度扩展它)。

【讨论】:

  • 是的。请注意,您实际上不需要使用复制的版本。原件被修剪(!)。
  • 这很聪明。谢谢!
  • 至少在 GrepCode 上的 openjdk source 中,在您指定初始大小且数组不需要增长的情况下,不会修剪原始文件。
【解决方案2】:

您可能会从压缩的 BitSet 替代方案中受益。例如:

https://github.com/lemire/javaewah

http://roaringbitmap.org/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多