我刚刚注意到一些关于 for 循环性能的问题似乎与 Google Android 团队给出的建议背道而驰。看下面的代码:
package com.jackcholt;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loopTest();
finish();
}
private void loopTest() {
final long loopCount = 1228800;
final int[] image = new int[8 * 320 * 480];
long start = System.currentTimeMillis();
for (int i = 0; i < (8 * 320 * 480); i++) {
image[i] = i;
}
for (int i = 0; i < (8 * 320 * 480); i++) {
image[i] = i;
}
Log.i("loopTest", "Elapsed time (recompute loop limit): " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < 1228800; i++) {
image[i] = i;
}
for (int i = 0; i < 1228800; i++) {
image[i] = i;
}
Log.i("loopTest", "Elapsed time (literal loop limit): " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < loopCount; i++) {
image[i] = i;
}
for (int i = 0; i < loopCount; i++) {
image[i] = i;
}
Log.i("loopTest", "Elapsed time (precompute loop limit): " + (System.currentTimeMillis() - start));
}
}
当我运行这段代码时,我在 logcat 中得到以下输出:
I/loopTest( 726): Elapsed time (recompute loop limit): 759
I/loopTest( 726): Elapsed time (literal loop limit): 755
I/loopTest( 726): Elapsed time (precompute loop limit): 1317
如您所见,似乎在循环的每次迭代中重新计算循环限制值的代码与使用循环限制的文字值的代码相比非常好。但是,使用包含循环限制的预计算值的变量的代码比其他任何一个都慢得多。我并不惊讶访问变量应该比使用文字更慢,但为什么看起来应该在循环的每次迭代中使用两条乘法指令的代码在性能上与文字相当?
会不会因为文字是唯一被乘法的东西,所以 Java 编译器正在优化乘法并使用预先计算的文字?
最佳答案
(8 * 320 * 480) 在构造 for 循环代码时绝对被优化为 1228800 作为“编译时常量”。
关于 final 的文档的关键要点是您没有获得不可变状态的特权,并且在构建 for 循环期间没有对此进行优化。即使它是一个局部变量,您也可以在 for 循环中修改它(尽管有 final 关键字),因此它不能转换为文字。
A final variable can only be assigned once. This assignment does not grant the variable immutable status.
关于android - For循环性能异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2707138/