为什么java中BitSet的内部数据存储为long[]而不是Java中的int[]?
Why is the internal data of BitSet in java stored as long[] instead of int[] in Java?
在java中,BitSet的内部数据存储为long[]而不是int[],我想知道为什么?这是 jdk 中的代码:
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
如果都是为了性能,我想知道为什么长[]存储会获得更好的性能。
肯定是一个优化问题:单个long
值最多存储64位,而int
仅32位。因此,任何64位以下的用户长度只需要一个条目 在数组中。如果它是 int
的数组,它将需要 两个条目 ,维护起来更慢且更重。
在 64 位机器上,对单个 long
值执行按位运算的性能明显高于对两个 int
值执行相同操作的性能,因为硬件直接支持 64 位值。在 32 位机器上,差异可能不是很大。
我可能是错的,但是使用 long[] 时 bitSet 的基数比使用 int[] 时大得多。因为数组的最大大小对于它们两者来说非常相似(但限于堆大小)。
基于对来源的粗略阅读 here。看起来,主要原因纯粹是为了表现。这是从源中检索到的评论。
BitSets are packed into arrays of "words." Currently a word is
a long, which consists of 64 bits, requiring 6 address bits.
The choice of word size is determined purely by performance concerns.
查询或操作单个位时,没有显着差异。您必须计算单词索引并读取该单词,并且在更新的情况下,操作该单词的一位并将其写回。 int[]
和 long[]
都是一样的。
有人可能会争辩说,如果您有真正的 32 位内存总线,使用 long
而不是 int
可能会增加必须为单个位操作传输的内存量, 但由于 Java 是上个世纪九十年代设计的,所以设计师认为这不再是问题。
另一方面,一次处理 多个 位时你会大获全胜。当您对整个 BitSet
执行 and
, or
or xor
等操作时,您可以在使用 long
数组时一次对整个字执行操作,读取 64 位。
类似地,当searching for the next set bit时,如果该位不在起始位置的字内,则随后的字首先进行零测试,这是一个内在的操作,即使对于大多数32位CPUs,所以你可以一次跳过64个零位,而第一个非零字肯定会包含下一个设置位,所以整个迭代只需要一个位提取操作。
批量操作的这些好处将超过任何与单位相关的缺点,如果有的话。如前所述,今天的大多数 CPU 都能够直接对 64 位字进行所有操作。
在java中,BitSet的内部数据存储为long[]而不是int[],我想知道为什么?这是 jdk 中的代码:
/**
* The internal field corresponding to the serialField "bits".
*/
private long[] words;
如果都是为了性能,我想知道为什么长[]存储会获得更好的性能。
肯定是一个优化问题:单个long
值最多存储64位,而int
仅32位。因此,任何64位以下的用户长度只需要一个条目 在数组中。如果它是 int
的数组,它将需要 两个条目 ,维护起来更慢且更重。
在 64 位机器上,对单个 long
值执行按位运算的性能明显高于对两个 int
值执行相同操作的性能,因为硬件直接支持 64 位值。在 32 位机器上,差异可能不是很大。
我可能是错的,但是使用 long[] 时 bitSet 的基数比使用 int[] 时大得多。因为数组的最大大小对于它们两者来说非常相似(但限于堆大小)。
基于对来源的粗略阅读 here。看起来,主要原因纯粹是为了表现。这是从源中检索到的评论。
BitSets are packed into arrays of "words." Currently a word is a long, which consists of 64 bits, requiring 6 address bits. The choice of word size is determined purely by performance concerns.
查询或操作单个位时,没有显着差异。您必须计算单词索引并读取该单词,并且在更新的情况下,操作该单词的一位并将其写回。 int[]
和 long[]
都是一样的。
有人可能会争辩说,如果您有真正的 32 位内存总线,使用 long
而不是 int
可能会增加必须为单个位操作传输的内存量, 但由于 Java 是上个世纪九十年代设计的,所以设计师认为这不再是问题。
另一方面,一次处理 多个 位时你会大获全胜。当您对整个 BitSet
执行 and
, or
or xor
等操作时,您可以在使用 long
数组时一次对整个字执行操作,读取 64 位。
类似地,当searching for the next set bit时,如果该位不在起始位置的字内,则随后的字首先进行零测试,这是一个内在的操作,即使对于大多数32位CPUs,所以你可以一次跳过64个零位,而第一个非零字肯定会包含下一个设置位,所以整个迭代只需要一个位提取操作。
批量操作的这些好处将超过任何与单位相关的缺点,如果有的话。如前所述,今天的大多数 CPU 都能够直接对 64 位字进行所有操作。