为什么java中的位集内部数据存储为long[]而不是int[]呢?

为什么java中的位集内部数据存储为long[]而不是int[]呢?,java,performance,bitset,Java,Performance,Bitset,在java中,的内部数据存储为long[],而不是int[],我想知道为什么?以下是jdk中的代码: /** * The internal field corresponding to the serialField "bits". */ private long[] words; 如果这都是关于性能的,我想知道为什么long[]存储会获得更好的性能。当然是一个优化问题:单个long值最多存储64位,而int仅存储32位。因此,任何长度小于64的用户只需要数组中的一个条目。如果它是一个

在java中,的内部数据存储为long[],而不是int[],我想知道为什么?以下是jdk中的代码:

 /**
 * The internal field corresponding to the serialField "bits".
 */
 private long[] words;

如果这都是关于性能的,我想知道为什么long[]存储会获得更好的性能。

当然是一个优化问题:单个
long
值最多存储64位,而
int
仅存储32位。因此,任何长度小于64的用户只需要数组中的一个条目。如果它是一个
int
数组,则需要两个条目,维护起来既慢又重。

在64位机器上,对单个
值执行逐位操作的性能明显高于对两个
int
值执行相同操作的性能,因为64位值直接受硬件支持。在32位机器上,差异可能不是很明显。

我可能错了,但使用long[]时,位集的基数比使用int[]时大得多。因为它们的最大数组大小非常相似(但仅限于堆大小)。

基于对源代码的粗略读取。看起来,主要原因纯粹是性能。这是从源检索到的注释

位集被压缩到“字”数组中。目前,一个字是 由64位组成的长地址,需要6个地址位。 字长的选择完全取决于性能问题


当查询或操作单个位时,没有显著差异。您必须计算单词索引并读取该单词,并且在更新的情况下,操纵该单词的一位并将其写回。这对于
int[]
long[]
都是一样的

有人可能会争辩说,如果使用真正的32位内存总线,那么使用
long
而不是
int
可以提高单位操作所需传输的内存量,但由于Java是在上世纪90年代设计的,设计者认为这不再是一个问题

另一方面,当一次处理多个位时,您将获得巨大的成功。当您在整个
位集
上执行诸如或之类的操作时,您可以在使用
数组时一次对整个字执行操作,读取64位

类似地,如果该位不在起始位置的字内,则随后的字将首先针对零进行测试,这是一种内在操作,即使对于大多数32位CPU,因此您可以一次跳过64个零位,而第一个非零字肯定会包含下一个设置位,因此,整个迭代只需要一个位提取操作



批量操作的这些好处将超过任何与单个位相关的缺点(如果有的话)。如前所述,当今大多数CPU都能够直接对64位字执行所有操作。

我想知道为什么不能?将其存储为int[]究竟有什么更好的方法呢?如果我不得不猜测的话,我会说这可能与以下事实有关:现在大多数人都在64位机器/操作系统上,因此长时间的操作往往得到更好的支持/更快。我真的不相信桑蒂的观点。我认为“大多数人使用64位”确实是一个非常大胆的说法。除了轶事之外,你还有其他证据支持这一点吗?考虑到Java被设计为在无数平台(包括许多嵌入式系统)上运行,我真的不认为这是设计决策背后的原因。@daiscog:但是他们选择了long而不是int。如果你看一下位集的源代码,就会清楚地看到:“位集被打包成“单词”数组。”@Ownedelysium对不起,我想你可能误解了我的意思。我知道他们选择了long而不是int,但我的意思是,我不相信你给出的原因是他们为什么这么做。为什么速度较慢,为什么维护起来更困难?显然,在一个数组中存储两个项目比只存储一个项目需要两倍的时间。不一定。这在很大程度上取决于您的硬件。我不是指内联存储值,而是指在循环中存储值,这是像BitSet这样的通用解决方案中的场景:
for(int I=0;对我来说,正是如此。如果我在设计类,出于这个原因,我会选择一个长数组(除了我不同意的“更重的维护”)。这从表面上看是有意义的;数组的最大元素意味着一个长数组可以提供更多可能的位。但是,我认为,对于想要有那么多标志的用例来说,这并不是一个足够现实的问题,因此不可能成为真正的原因。
BitSet
的方法使用
int
索引参数并返回val因此,由于API的原因,UE被限制为2位。因此,内部数组施加的理论限制是32倍还是64倍并不重要。即使是
字节
数组也可以存储比API支持的更多的位。是的,位集内部数组是用整数索引的,但值很长,因此我们得到的是more使用int时可能保留的位。我不是指数组索引,而是指
位集
的API。尝试使用大于2的位-这是不可能的,因为没有提供该操作的方法。类似地,返回
int
。因此使用
long[]不会获得更多位
而不是
int[]
内部。目前的API最多只能有2个字符。如果这都是为了性能,我想知道为什么长[]存储会获得更好的性能。类将其容量调整64比32更快。在32位机器上,int[]或长[]的性能会更好吗?@displayName,您可以编写自己的基于int[]的
位集并自己测试:-)另请参见@Holger answer@displayName我会说int[],因为它是本机的:D,但Tagir是正确的。。。我们应该执行和执行see@TagirValeev:你的回答