在Java中,BitSet的内部数据存储为long[]而不是int[],我想知道原因?以下是JDK中的代码:
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
如果说性能是最重要的,那我想知道为什么使用 long[] 存储会得到更好的性能。
在Java中,BitSet的内部数据存储为long[]而不是int[],我想知道原因?以下是JDK中的代码:
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
如果说性能是最重要的,那我想知道为什么使用 long[] 存储会得到更好的性能。
在64位机器上,对单个long
值进行按位操作比对两个int
值进行相同操作要更具有性能优势,因为硬件直接支持64位值。在32位机器上,差异可能不是非常显著。
BitSet
类有所了解,并在操作不够“本地化”时替换某些操作。更大的障碍是找到一个适当的测试机器,具有真正的 32位架构... - Holger当查询或操作单个位时,没有太大的区别。您必须计算字索引并读取该字,在更新的情况下,操作该字的一个位并将其写回。这对于int []
和long []
都是一样的。
有人可能会认为,使用long
而不是int
进行操作,如果您有一个真正的32位内存总线,可能会增加必须传输的内存量,但是由于Java是设计于上世纪九十年代,设计者认为这不再是一个问题。
另一方面,当同时处理多个位时,你会获得巨大的优势。当执行像and
、or
或xor
这样的操作时,你可以在使用long
数组时一次性地对整个字进行操作,读取64位。
同样,当查找下一个设置的位时,如果该位不在起始位置的字中,则首先将后续字与零进行比较,这是一个内在操作,即使对于大多数32位CPU也是如此,因此您可以一次跳过64个零位,而第一个非零字一定会包含下一个设置的位,因此整个迭代只需要一个位提取操作。
如果有单位相关的缺点,这些针对批量操作的优势将超过它们。正如所说,今天的大多数CPU都能够直接在64位字上执行所有操作。
BitSet被打包成“words”数组。目前,一个word是long类型,由64位组成,需要6个地址位。word大小的选择完全基于性能考虑。
long[] storage
会获得更好的性能。 - jerry_sjtulong
值最多可以存储 64 位,而 int
只有 32 位。因此,任何长度小于 64 的用户只需要在数组中有 一个条目。如果它是一个int
数组,就需要 两个条目,这样会更慢,也更难以维护。for (int i=0;i<n;i++) {array[i]=0;}
比n==1时需要更多的时间。 - Little SantiBitSet
的方法使用 int
索引参数和返回值,因此由于 API 的限制,它们仅限于 2³¹ 位。因此,其内部数组所施加的理论限制比实际限制高32倍或64倍并不重要。即使是 byte
数组也能存储比 API 支持的更多位。 - Holger