首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么添加局部变量会导致方法延迟?

为什么添加局部变量会导致方法延迟?
EN

Stack Overflow用户
提问于 2014-09-16 08:21:47
回答 2查看 239关注 0票数 8

最近,我开始阅读关于基准测试的文章,并为Android编写它们(用Java编写)。我知道诸如翘曲、垃圾收集器和编译器优化之类的问题,但不知道我面临的问题是否是这些问题中的任何一个。

在我的基准应用程序中,我创建了一个由10,000个浮动变量组成的数组,并使用随机值初始化它。运行基准代码时:

代码语言:javascript
复制
private void runMinorBenchmarkFloat (float[] array) {
        float sum = 0;
        long startTime;
        long endTime; 

        /* Fast warm-up */
        startTime = System.nanoTime();
        for(int i=0; i<SMALL_LOOP_ITERATION_COUNT; i++)
            for(int j=0; j<TAB_SIZE; j++)
                sum += array[j];
        endTime = System.nanoTime() - startTime;
        postMessage("Warm-up for FLOAT finished in: " + endTime/1000000 + "ms.\n");

        /* Main benchmark loop */
        startTime = System.nanoTime();
        for(int i=0; i<BIG_LOOP_ITERATION_COUNT; i++)
        {
            sum = 0;
            for(int j=0; j<TAB_SIZE; j++)
                sum += array[j];
        }
        endTime = System.nanoTime() - startTime;
        postMessage("Benchmark for FLOAT finished in: " + endTime/1000000 + "ms.\n");
        postMessage("Final value: " + sum + "\n\n");
    }

在我的手机上,热身的时间大约是2秒,“真实”循环的时间是20秒。

现在,当我再添加两个浮点变量(sum2和sum3 -在方法中从未使用):

代码语言:javascript
复制
private void runMinorBenchmarkFloat (float[] array) {
        float sum = 0, sum2 = 0, sum3 = 0; // <------- the only code change here!!!
        long startTime;
        long endTime; 

        /* Fast warm-up */
        startTime = System.nanoTime();
        for(int i=0; i<SMALL_LOOP_ITERATION_COUNT; i++)
            for(int j=0; j<TAB_SIZE; j++)
                sum += array[j];
        endTime = System.nanoTime() - startTime;
        postMessage("Warm-up for FLOAT finished in: " + endTime/1000000 + "ms.\n");

        /* Main benchmark loop */
        startTime = System.nanoTime();
        for(int i=0; i<BIG_LOOP_ITERATION_COUNT; i++)
        {
            sum = 0;
            for(int j=0; j<TAB_SIZE; j++)
                sum += array[j];
        }
        endTime = System.nanoTime() - startTime;
        postMessage("Benchmark for FLOAT finished in: " + endTime/1000000 + "ms.\n");
        postMessage("Final value: " + sum + "\n\n");
    }

执行时间从热身的2秒跃升到5秒,真正循环的执行时间从20秒提高到50秒。

常数:

代码语言:javascript
复制
SMALL_LOOP_ITERATION_COUNT = 100,000 
BIG_LOOP_ITERATION_COUNT = 1,000,000

你认为这种差异可能是由对齐问题(只是松散的想法)引起的吗?

事先谢谢你的回答。

编辑:

似乎这个错误并不会出现在每个设备上。我可以在三星银河S5上复制它。该项目的主要目标是制定很少的基准。我执行了四个几乎相同的函数(runMinorBenchmark____,其中_要么是: int、short、float、double),它们仅在变量'sum‘类型上有所不同。在主基准函数中,我调用了这些函数。由于发生了上述错误,我决定将这些函数合并成一个大函数。现在..。在运行测试时,我有这样的时间:1.37640。( int) 2.46728 int。(简称)3.60589毫秒。(浮子)4.34467ms。(双倍)

我知道,由于类型的铸造,短片意味着要慢一些。我还认为浮子应该慢一点,以防将其转换成双倍(也许FPU每次都会将类型转换为双倍)。但是,当我将sumFloat的变量类型从浮动改为双倍时,浮动的时间与双倍的时间是相同的。我还在另一个设备上做了这个“基准”,它似乎没有受到这种奇怪行为的影响,每次测试的时间几乎相同:~45000毫秒。(实际上没有明显的差别)。

Dalvik VM错误(?)

EN

回答 2

Stack Overflow用户

发布于 2014-09-19 15:26:38

我不相信这是你麻烦的原因。难道编译器就会丢弃那些未使用的变量吗?您确定输入数组没有改变,或者您的常量,或者TAB_SIZE

如果您仍然确定,可以通过运行类似的命令并在这里粘贴输出来证明这一点:

代码语言:javascript
复制
public void proveIt() {
    float[] inputArray = new float[10000];
    for (int i = 0; i < 10000; i++) {
        inputArray[i] = 1;
    }

    postMessage("Without declaration:");
    runMinorBenchmarkFloatA(inputArray);

    postMessage("With declaration:");
    runMinorBenchmarkFloatB(inputArray);

    postMessage("And again just to make sure...");

    postMessage("Without declaration:");
    runMinorBenchmarkFloatA(inputArray);

    postMessage("With declaration:");
    runMinorBenchmarkFloatB(inputArray);
}

long TAB_SIZE = 10000;
long SMALL_LOOP_ITERATION_COUNT = 100000;
long BIG_LOOP_ITERATION_COUNT = 1000000;

private void runMinorBenchmarkFloatA(float[] array) {
    float sum = 0;
    long startTime;
    long endTime;

    /* Fast warm-up */
    startTime = System.nanoTime();
    for (int i = 0; i < SMALL_LOOP_ITERATION_COUNT; i++)
        for (int j = 0; j < TAB_SIZE; j++)
            sum += array[j];
    endTime = System.nanoTime() - startTime;
    postMessage("Warm-up for FLOAT finished in: " + endTime
            / 1000000 + "ms.\n");

    /* Main benchmark loop */
    startTime = System.nanoTime();
    for (int i = 0; i < BIG_LOOP_ITERATION_COUNT; i++) {
        sum = 0;
        for (int j = 0; j < TAB_SIZE; j++)
            sum += array[j];
    }
    endTime = System.nanoTime() - startTime;
    postMessage("Benchmark for FLOAT finished in: " + endTime
            / 1000000 + "ms.\n");
    postMessage("Final value: " + sum + "\n\n");
}

private void runMinorBenchmarkFloatB(float[] array) {
    float sum = 0, sum2 = 0, sum3 = 0;
    long startTime;
    long endTime;

    /* Fast warm-up */
    startTime = System.nanoTime();
    for (int i = 0; i < SMALL_LOOP_ITERATION_COUNT; i++)
        for (int j = 0; j < TAB_SIZE; j++)
            sum += array[j];
    endTime = System.nanoTime() - startTime;
    postMessage("Warm-up for FLOAT finished in: " + endTime
            / 1000000 + "ms.\n");

    /* Main benchmark loop */
    startTime = System.nanoTime();
    for (int i = 0; i < BIG_LOOP_ITERATION_COUNT; i++) {
        sum = 0;
        for (int j = 0; j < TAB_SIZE; j++)
            sum += array[j];
    }
    endTime = System.nanoTime() - startTime;
    postMessage("Benchmark for FLOAT finished in: " + endTime
            / 1000000 + "ms.\n");
    postMessage("Final value: " + sum + "\n\n");
}
票数 2
EN

Stack Overflow用户

发布于 2014-09-22 06:28:26

现在,当我再添加两个浮点变量(sum2和sum3 -在方法中从未使用):

代码语言:javascript
复制
float sum = 0, sum2 = 0, sum3 = 0; // <------- the only code change here!!!

但是在该方法中使用了sum2sum3。它们被初始化为零。这需要时间。

如果没有初始化它们,则生成的字节代码将与它们相同或不相同,除了所分配的堆栈帧的大小之外,这不会影响定时。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25863888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档