For-Loop Performance Oddity

时间:2010-04-25 04:21:40

标签: android for-loop

我刚刚注意到有关for-loop性能的一些内容似乎是面对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编译器正在优化乘法并使用预先计算的文字吗?

1 个答案:

答案 0 :(得分:3)

当构造for循环代码时,

(8 * 320 * 480)绝对优化为1228800作为'编译时常量'。

关于final的文档的关键点是你没有获得不可变状态的特权,并且在构造for循环期间没有对其进行优化。即使它是一个局部变量,你也可以在for循环中修改它(尽管 final 关键字),因此无法将其转换为文字。

  

只能分配最终变量   一旦。此作业不授予   变量不可变状态。