最近看 HashMap 的源码。有一个 tableSizeFor
方法,原来在 JDK7 的时候,这个方法叫做 roundUpToPowerOf2
:
static int roundUpToPowerOf2(int cap) {
return cap >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
: (cap > 1) ? Integer.highestOneBit((cap - 1) << 1) : 1;
}
在 JDK8 的时候给改成了这样:
static int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
但是在 JDK11 的时候,对这块又进行了一个优化,可以参考 JDK-8203279, 给改成了下面的代码:
static int tableSizeFor(int cap) {
int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
这个方法的用途其实没有变: 都是计算返回大于等于 cap 且与之最接近的一个 2 的次幂值。 为了验证这个方法的性能,我用 JHM 跑了一下基准测试,测试代码:
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热 2 轮,每次 1s
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 测试 5 轮,每次 1s
@Fork(1)
@State(Scope.Thread)
public class TableSizeForTest {
static final int MAXIMUM_CAPACITY = 1 << 30;
static final int roundSize = 100_000_000;
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(TableSizeForTest.class.getSimpleName())
.build();
new Runner(opt).run();
}
@Benchmark
public void jdk8() {
for (int i = 1; i <= roundSize; i++) {
tableSizeFor(i);
}
}
@Benchmark
public void jdk7() {
for (int i = 1; i <= roundSize; i++) {
roundUpToPowerOf2(i);
}
}
@Benchmark
public void jdk11() {
for (int i = 1; i <= roundSize; i++) {
tableSizeFor_JDK11(i);
}
}
// 字数原因不贴 tableSizeFor 方法了
}
最后结果如下:
Benchmark Mode Cnt Score Error Units
TableSizeForTest.jdk11 avgt 5 88015092.847 ± 57126449.190 ns/op
TableSizeForTest.jdk7 avgt 5 0.397 ± 0.042 ns/op
TableSizeForTest.jdk8 avgt 5 123458345.756 ± 2528234.087 ns/op
可以看到,jdk11 确实比 jdk8 的性能提高了不少,但是 相比于 jdk7 时使用的 roundUpToPowerOf2 方法,差距也太大了,有大佬能给说一下这是我测试的问题,还是说确实就是这样?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.