让我们看看以下两个java方法:
static void performance1() {
int a=0;
int b=0;
int[] arrayA = { 3, 4, 5 };
int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
for (int k = 0; k < 100; k++) {
a = arrayA[2];
b = arrayB[1];
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
static void performance2() {
int a=0;
int b=0;
int[] arrayA = { 3, 4, 5 };
int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
for (int k = 0; k < 100; k++) {
b = arrayB[arrayA[2]];
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
第一种方法需要209 ms才能在我的系统上执行,即秒4295!这么多20倍。怎么会这样?据我所知,如果我声明3个单独的变量而不是arrayA,我可以获得20倍的性能提升,因为以下方法再次执行得非常快:
static void performance3() {
int a=0;
int b=0;
int[] arrayA = { 3, 4, 5 };
int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
for (int k = 0; k < 100; k++) {
b = arrayB[a];
}
}
long end = System.currentTimeMillis();
System.out.println(end - start);
}
我是否忽视了一些明显的东西?对我来说,差异是如此巨大,这真的让我感到惊讶。无论如何,谢谢你的解释:)
答案 0 :(得分:1)
执行b = arrayB[1];
时,它会直接引用位置1
中存储的值,但当您执行b = arrayB[arrayA[2]];
时,必须首先检索值arrayA[2]
,然后检索值arrayB[]
的{{1}}基于前一步骤中的值检索。
编译器非常智能,可以在第一步中优化活动,但不能在第二步中优化活动。
如果查看这两种方法生成的字节代码,将会更清楚。
答案 1 :(得分:1)
在第一个代码中,a总是设置为5而b设置为5,无论你的循环索引是什么,所以编译器完全消除了循环,所以它最终会像:
int a=0;
int b=0;
int[] arrayA = { 3, 4, 5 };
int[] arrayB = { 4, 5, 6, 3, 4, 5, 6, 7, 8, 4 };
long start = System.currentTimeMillis();
a = 5;
b = 5;
long end = System.currentTimeMillis();
System.out.println(end - start);