在java中,BitSet的内部数据存储为long []而不是int [],我想知道为什么?这是jdk中的代码:
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
如果关于性能,我想知道为什么长[]存储会获得更好的性能。
答案 0 :(得分:11)
在64位计算机上,对单个long
值执行按位运算的性能明显高于对两个int
值的相同操作,因为硬件直接支持64位值。在32位机器上,差异可能不是很大。
答案 1 :(得分:10)
查询或操作单个位时,没有显着差异。您必须计算单词索引并读取该单词,并且在更新的情况下,操纵该单词的一位并将其写回。对int[]
和long[]
来说,情况完全相同。
有人可能会说,如果你有一个真正的32位内存总线,那么使用long
代替int
来实现它可能会增加单个位操作必须传输的内存量,但是由于Java是在上世纪九十年代设计的,设计师们认为这不再是一个问题了。
另一方面,在一次处理多个位时,您获得了巨大的胜利。当您在整个BitSet
上执行and
,or
或xor
等操作时,您可以在使用时对整个字执行操作,一次读取64位long
数组。
类似地,当searching for the next set bit时,如果该位不在起始位置的字内,则后续字首先针对零进行测试,这是一个固有操作,即使对于大多数32位CPU,也可以跳过同时64个零位,而第一个非零字肯定包含下一个设置位,因此整个迭代只需要一个位提取操作。
批量操作的这些好处将超过任何单位相关的缺点,如果有的话。如上所述,今天的大多数CPU都能够直接对64位字进行所有操作。
答案 2 :(得分:6)
基于粗略阅读来源here。似乎,主要原因纯粹是为了表现。这是从源检索到的评论。
BitSet被打包成"字数组。"目前一句话就是 long,由64位组成,需要6个地址位。 字大小的选择完全取决于性能问题。
答案 3 :(得分:1)
肯定是一个优化问题:单个long
值最多可存储64位,而int
仅存储32个。因此,64岁以下的任何用户长度仅需一个条目在数组中。如果它是int
的数组,那么它将需要两个条目,这要维护得更慢更重。
答案 4 :(得分:1)
我可能错了,但是使用long [],bitSet的基数比使用int []时要大得多。因为两个数组的最大大小非常相似(但仅限于堆大小)。