Java 2D数组填充 - 无辜的优化导致可怕的减速
我尝试通过计算两个元素的每个总和来优化正方形二维Java数组的填充,其中包含每个元素的索引和,相对于主对角线相反。但是,我没有加速,或者至少是可比的性能,而是代码慢了23(!)倍。
我的代码:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(ArrayFill.N * ArrayFill.N)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class ArrayFill {
public static final int N = 8189;
public int[][] g;
@Setup
public void setup() { g = new int[N][N]; }
@GenerateMicroBenchmark
public int simple(ArrayFill state) {
int[][] g = state.g;
for(int i = 0; i < g.length; i++) {
for(int j = 0; j < g[i].length; j++) {
g[i][j] = i + j;
}
}
return g[g.length - 1][g[g.length - 1].length - 1];
}
@GenerateMicroBenchmark
public int optimized(ArrayFill state) {
int[][] g = state.g;
for(int i = 0; i < g.length; i++) {
for(int j = 0; j <= i; j++) {
g[j][i] = g[i][j] = i + j;
}
}
return g[g.length - 1][g[g.length - 1].length - 1];
}
}
基准测试结果:
Benchmark Mode Mean Mean error Units
ArrayFill.simple avgt 0.907 0.008 ns/op
ArrayFill.optimized avgt 21.188 0.049 ns/op
问题:
如何解释如此巨大的性能下降?
P. S. Java 版本是 1.8.0-ea-b124,64 位 3.2 GHz AMD 处理器,基准测试在单个线程中执行。