BitSet值得使用吗?

时间:2015-06-04 22:37:20

标签: java memory-management bitset

我创建了一个包含很多布尔字段的Java对象。当我开始质疑它的用处时,我正在考虑使用BitSet

当然,人们会因为内存原因而使用它,因为boolean仅为8位,数组为4位。使用BitSet,每个值都存储为单个位。 然而,由于以下开销,所节省的内存不会被吹出水面吗?

  • BitSet类和方法定义元数据(每个运行时)
  • 对象需要作为键来语义检索值(每个类使用BitSet
  • bits(每个实例)
  • BitSet数组的元数据

与使用boolean s:

  • 布尔值(每个实例)

让我们来看看下面的课程:

private boolean isVisible; // 8 bits per boolean * 82 booleans = ~0.6Kb
// 81 lines later...
private boolean isTasty;

// ...

public boolean isVisible() { return isVisible; }
// ...
public boolean isTasty() { return isTasty; }

public void setVisible(boolean newVisibility) { isVisible = newVisibility; }
// ...
public void setTasty(boolean newTastiness) { isTasty = newTastiness; }

现在,如果我将所有boolean合并为一个BitSet并仍保持我的代码语义,我可能会这样做:

private static final int _K_IS_VISIBLE = 1; // 32 bits per key * 82 keys = ~2.5Kb
// ...
private static final int _K_IS_TASTY = 82;
private BitSet bools = new BitSet(82); // 2 longs = 64b

// ...

public boolean isVisible() { return bools.get(_K_IS_VISIBLE); }
// ...
public boolean isTasty() { return bools.get(_K_IS_TASTY); }

public void setVisible(boolean newVisibility) { bools.set(_K_IS_VISIBLE, newVisibility); }
// ...
public void setTasty(boolean newTastiness) { bools.set(_K_IS_TASTY, newTastiness); }

TL;博士

costOfUsingBitSet =
    bitSetMethodsAndClassMetaData + // BitSet class overhead
    (numberOfKeysToRetrieveBits * Integer.SIZE) + // Semantics overhead
    (numberOfBitSetsUsed * floor((bitsPerBitSet / Long.SIZE) + 1)); // BitSet internal array overhead

甚至更多。而使用boolean s将是:

costOfBooleans = 
    (numberOfBooleansOutsideArrays * 8) + 
    (numberOfBooleansInsideArrays * 4);

我觉得BitSet的开销要高得多。我是对的吗?

1 个答案:

答案 0 :(得分:3)

BitSet将减少内存,仅使用一位更有效。您正在查看的方法开销是一次,无论您的班级有多少实例,因此其成本基本上摊销为0

booleanbooleanBitSet数组的优势在于它不是Object,因此您只有一个较低级别的间接< / p>

缓存命中是性能的主要驱动因素,因此您需要权衡较少的缓存命中率,以及由于内存消耗较高而从缓存中逐出数据的可能性较高

粗略地说,一些boolean会更快但更多的记忆,因为你有更多的字段或更接近大数字,规模将高于BitSet