我刚刚阅读了《Java杂志》的文章《循环展开》。在那里,作者展示了简单的for
循环与int
计数器一起编译时会优化为循环展开:
private long intStride1()
{
long sum = 0;
for (int i = 0; i < MAX; i += 1)
{
sum += data[i];
}
return sum;
}
然而,当计数器类型切换为long
时,他们表明一切都会发生变化:
private long longStride1()
{
long sum = 0;
for (long l = 0; l < MAX; l++)
{
sum += data[(int) l];
}
return sum;
}
这将改变输出程序集,方式如下:
- 引入Safepoints
- 不执行unrolling(循环展开优化)
这会极大地降低吞吐量性能。
为什么64位HotSpot VM不对long
计数器执行循环展开优化?为什么第二种情况需要Safepoints,而第一种情况则不需要?