gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:00:09 24 4
gpt4 key购买 nike

我最近开始阅读有关基准测试的内容并为 Android(用 Java)编写它们。我知道预热、垃圾收集器和编译器优化等问题,但不知道我遇到的问题是否可能是由这些问题引起的。

在我的基准测试应用程序中,我创建了一个包含 10,000 个浮点变量的数组并使用随机值对其进行初始化。运行基准代码时:

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 - 从未在方法内部使用过)时:

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 秒。

常量:

SMALL_LOOP_ITERATION_COUNT = 100,000 
BIG_LOOP_ITERATION_COUNT = 1,000,000

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

提前感谢您的回答。

编辑:

似乎这个错误并没有出现在每台设备上。我可以在三星 Galaxy S5 上重现它。该计划的主要目标是做一点基准。我做了四个几乎相同的函数(runMinorBenchmark____,其中 _ 是:int、short、float、double),它们仅在变量“sum”类型上有所不同。在主要基准函数中,我调用了这些函数。因为发生了上述错误,所以我决定将这些功能合并为一个大功能。现在......运行测试时我有这样的时间: 1. 37640 毫秒。 (对于整数) 2. 46728 毫秒。 (简称) 3. 60589 毫秒。 (用于 float ) 4. 34467 毫秒。 (双)

我知道由于类型转换,short 意味着更慢。我还认为 float 在将其转换为 double 时应该更慢(也许 FPU 每次都将类型转换为 double(?))。但是当我将 sumFloat 的变量类型从 float 更改为 double 时,float 的时间与 double 时间相同。我还在另一台设备上做了这个“基准测试”,它似乎没有受到这种奇怪行为的影响,而且每次测试的时间几乎相同:~45000 毫秒。 (确实没有明显的差异)。

Dalvik 虚拟机错误(?)

最佳答案

我不相信这是你麻烦的原因。编译器肯定只是把那些未使用的变量扔掉了吗?您确定输入数组、常量或 TAB_SIZE 没有变化吗?

如果您仍然确定,请通过运行类似的程序并将输出粘贴到此处来证明这一点:

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");
}

关于java - 为什么添加局部变量会导致方法延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25863888/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com