我尝试用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
问题:
如何解释这种如此巨大的性能下降?
附言:Java版本为1.8.0-ea-b124,64位3.2 GHz AMD处理器,基准测试在单线程中执行。
8189
远离8192
,性能会发生如何的变化? - Mysticial