Java的For循环和While循环,奇怪的行为和时间性能

3
我正在编写一个算法,它会在整数数组上进行一次大循环,从末尾向开始遍历,并带有一个if条件。第一次条件为false时,循环可以终止。
因此,使用for循环,如果条件为false,它将继续迭代并进行简单变量更改。 使用while循环作为条件的while参数,一旦条件为false,循环将停止,并且应该保存一些迭代。
然而,while循环仍然比for循环慢一点!
但是,如果我将int值作为计数器,并计算迭代次数,则For循环如预期地执行了更多的迭代。 但是这一次,具有计数器的修改后的For方法的执行时间将比具有计数器的while方法慢得多!
有什么解释吗?
以下是使用for循环的代码:
for (int i = pairs.length - 1; i >= 0; i -= 2) {
    //cpt++;
    u = pairs[i];
    v = pairs[i - 1];

    duv = bfsResult.distanceMatrix.getDistance(u, v);

    if (duv > delta) {
        execute();
    }
}

执行时间:6473
使用计数器的执行时间:8299
迭代次数:2584401

以下是带有 while 循环的代码:

int i = pairs.length - 1;

u = pairs[i];
v = pairs[i - 1];

duv = bfsResult.distanceMatrix.getDistance(u, v);

while (duv > delta) {
    //cpt++;
    execute();

    u = pairs[i -= 2];
    v = pairs[i - 1];
    duv = bfsResult.distanceMatrix.getDistance(u, v);
}

时间执行:6632
带计数器的时间执行:7163
迭代次数:9793

时间以毫秒为单位,我用不同大小的实例重复了这个实验,测量结果几乎相同。execute()方法更新delta值。getDistance()方法只是访问矩阵int[][]。

谢谢任何帮助。


1
你可以使用两个循环来完成完全相同的事情。例如:你可以在 duv <= delta 时中断 for 循环。 - Mister Smith
你在使用什么单位来测量时间?毫秒吗?如果是的话,我认为你正在面临微基准测试问题。 - Bob Cross
我同意,我的问题是为什么时间几乎与 while 循环一样,因为它执行了更多的迭代。为什么当我放一个简单的计数器时,它变得更“正常”? - Aurélien
但是,我猜我应该看一下Pavel_Kazlou提到的Java基准测试和技巧。 - Aurélien
3个回答

4

在尝试对Java执行任何性能测试之前,我强烈建议您阅读本文http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html

简而言之,当Hotspot启用JVM运行一段时间后,可以优化您的代码,这将影响测试结果。因此,您需要适当的技术来测试代码的性能。为了减轻痛苦,有一个库可用于执行适当的测试:http://ellipticgroup.com/html/benchmarkingArticle.html。您可以在此页面上找到文章的两个部分的链接。

更新:为帮助您更快地开始,请执行以下操作:

  1. 下载页面上找到的bb.jar、jsci-core.jar和mt-13.jar
  2. 将它们放在类路径上
  3. 重写您的代码,使while循环方法和for循环方法都进入Runnable或Callable接口的单独实现中
  4. 在您的主方法中只需调用

System.out.println(new Benchmark(new WhileApproach()));

为了展示while循环的执行时间,显然

System.out.println(new Benchmark(new ForApproach()));

为了获取for循环的信息

@Aurélien 更新了答案 - 如果你对过多的理论感到厌烦,请看一下快速入门 ;) - pavel_kazlou
非常感谢,这再简单不过了! - Aurélien
@Aurélien,你有使用库进行测试吗?结果如何? - pavel_kazlou

1

你的终止条件不同。对于 while 循环,它是:

duv > delta

对于for循环,它是这样的

i >= 0

这两种情况并不相等。我猜测 while 循环条件变为 false 的时间比 for 循环要早,因此执行的迭代次数较少。

没错,那为什么for循环几乎比while循环更快呢? - Aurélien

0

duv>delta 时,while 循环停止,但 for 循环继续。两者得到相同的结果,但是 for 继续检查。你应该像这样修改 for 循环: if (duv > delta) { execute(); } else break;


你没有正确阅读问题。for循环实际上比while循环更快,即使它执行更多的迭代。 - Antoine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接