currentHashMap定位获取指定index的Node
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}
i是获取的Node在数组中的索引值
正常的处理是采用arrayBaseOffset + i *arrayIndexScale
此处采用arrayBaseOffset +i<<(31 - Integer.numberOfLeadingZeros(arrayIndexScale))
首先有个前提,arrayIndexScale是2的整数次幂
int scale = U.arrayIndexScale(ak);
if ((scale & (scale - 1)) != 0)
throw new Error("data type scale not a power of two");
证明 i *arrayIndexScale == i<<(31 - Integer.numberOfLeadingZeros(arrayIndexScale))
假设arrayIndexScale = 2^n
即证明n = 31 - Integer.numberOfLeadingZeros(arrayIndexScale)
Integer.numberOfLeadingZeros(arrayIndexScale) = 32 - (n +1) = 31 -n
相等
采用等价的位运算相必是为了提升效率,但是实测好像并不能提升效率
int scale = 1<<2; //scale 是2的整数幂
long s1 = System.nanoTime();
for(int i =0;i<10000;i++) {
int j = scale * i ;
}
long s2 = System.nanoTime();
for(int i =0;i<10000;i++) {
int j = i << (31 - Integer.numberOfLeadingZeros(scale));
}
long s3 = System.nanoTime();
System.out.println(s2 - s1);
System.out.println(s3 - s2);
结果
70907
372259
反而采用位运算的耗时更长,不排除偶然性