Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比特集值得使用吗?_Java_Memory Management_Bitset - Fatal编程技术网

Java 比特集值得使用吗?

Java 比特集值得使用吗?,java,memory-management,bitset,Java,Memory Management,Bitset,我制作了一个Java对象,它有很多布尔字段。当我开始质疑它的有用性时,我正在考虑使用它 当然,出于内存原因,可以使用它,因为布尔值是8位,一个数组中有4位。使用位集,每个值存储为单个位但是,节省下来的内存不是会被以下开销吹出水面吗? 位集类和方法定义元数据(每个运行时) 语义检索值所需的键对象(每个类使用位集) 位集中位数组的元数据(每个实例) 与使用booleans相比: 布尔值(每个实例) 让我们看一下下面的课程: 私有布尔值可见;//每布尔值8位*82布尔值=~0.6Kb //8

我制作了一个Java对象,它有很多布尔字段。当我开始质疑它的有用性时,我正在考虑使用它

当然,出于内存原因,可以使用它,因为
布尔值是8位,一个数组中有4位。使用
位集
,每个值存储为单个位但是,节省下来的内存不是会被以下开销吹出水面吗?

  • 位集
    类和方法定义元数据(每个运行时)
  • 语义检索值所需的键对象(每个类使用
    位集
  • 位集中
    数组的元数据(每个实例)
与使用
boolean
s相比:

  • 布尔值(每个实例)

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

私有布尔值可见;//每布尔值8位*82布尔值=~0.6Kb
//81行之后。。。
私人住宅;
// ...
公共布尔值isVisible(){return isVisible;}
// ...
公共布尔值isTasty(){return isTasty;}
public void setVisible(布尔newVisibility){isvisibility=newVisibility;}
// ...
public void setTasty(布尔newTastiness){isTasty=newTastiness;}
现在,如果我将所有的
布尔值
组合成一个
位集
,并且仍然保持代码的语义,我可能会这样做:

private static final int\u K\u是可见的=1;//每个密钥32位*82个密钥=~2.5Kb
// ...
私有静态final int_K_是_TASTY=82;
私有位集bools=新位集(82);//2长=64b
// ...
公共布尔值isVisible(){return bools.get(_K_IS_VISIBLE);}
// ...
公共布尔isTasty(){return bools.get(_K_是_TASTY);}
public void setVisible(boolean newVisibility){bools.set(_K_是_visibility,newVisibility);}
// ...
public void setTasty(boolean newTastiness){bools.set(_K_IS_TASTY,newTastiness);}

tl;博士
costOfUsingBitSet=
bitSetMethodsAndClassMetaData+//位集类开销
(numberOfKeystreeveBits*Integer.SIZE)+//语义开销
(使用的比特数*地板((比特比特比特集/长尺寸)+1));//位集内部数组开销
还有可能更多。而使用
boolean
s将是:

costOfBooleans=
(BooleanSoutSideArray的数量*8)+
(BooleansInSideArray的数量*4);

我觉得
位集的开销要高得多。我说得对吗?

位集
的内存会更少,只使用一个位的效率要高得多。不管您的类有多少个实例,您所看到的方法开销都是一次性的,因此它的成本基本上分摊到0

布尔
数组或
位集
相比,
布尔
的优势在于它不是
对象
,因此间接寻址级别减少了一个级别

缓存命中率是性能的主要驱动因素,因此您必须权衡缓存命中率越低,由于内存消耗越高,从缓存中逐出数据的可能性越高


粗略地说,几个
boolean
s会更快,但内存会更多,因为您有更多的字段或更接近于巨大的数字,规模会朝
位集的方向上升,您指出的内存开销不会存在于堆中,除非方法使用内部变量,如果您担心的话。此外,我们谈论的不是兆字节的内存消耗,而是位。除非你像心脏起搏器的软件一样构建一个关键的内存系统,否则这种担心是毫无价值的。@LuiggiMendoza我只关心整个系统的内存。这是Android的,所以我必须考虑512MB的设备。我们的应用程序已经非常庞大,因此,如果我们在整个过程中都使用这种方法,那么任何瘦身的方法都会有很大帮助。不管怎样,我的问题是:
BitSet
有什么好处?好吧,在阅读了Java 1.6的
BitSet
源代码之后,唯一会影响内存的字段是
private long[]words
private transient int wordsInUse=0
私有瞬态布尔值sizeIsSticky=false。您正在讨论的所有其他内容都应该已经由JVM为您加载,因此没有问题。我不会使用
BitSet
替换常量
boolean
s,只有在我可以拥有任意多个的情况下——例如,如果我替换任意
Set
。我不理解。在这两种情况下,您都可以为密钥指定名称。您还忽略了位集的空间效率和容量都比布尔数组大得多。你在比较苹果和桔子,你也在匆忙下结论;如果是,我会询问只执行
bools.set(1,false)所需的计算量位集将减少内存,只使用一个位的效率要高得多当然,我知道进去;这就是我考虑的原因。我问这个问题的原因是因为我担心在这1位周围会发生什么(长
long
s中未使用的位,长
long
s存储在其中的数组的元数据,
BitSet
类及其数组的元数据,
int
s需要作为检索位的键,等等)@如果你看到源代码,你会发现开销是不值得关注的。但同样,除非通过使用探查器证明自己使用其中一个最适合您的情况,否则您无法确定。@Suphustar“long中未使用的位”在您的示例中占7个字节,占一个长字节的7个字节,或总共8个字节。您的82个布尔数组占用82个字节。”需要作为键的
int
是局部变量,而不是实例变量,我无法理解您为什么会有不同的想法。