请参阅以下代码段:
Long first_begin = System.currentTimeMillis();
// first nested loops
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000000; j++) {
// do some stuff
}
}
System.out.println(System.currentTimeMillis() - first_begin);
// second nested loops
Long seconde_begin = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 10; j++) {
// do some stuff
}
}
System.out.println(System.currentTimeMillis() - seconde_begin);
我想知道为什么第一个嵌套循环的运行速度比第二个慢?
问候!
重要提示!:很抱歉,当我第一次提出这个问题时,我意外地将变量j从1开始,我已经进行了修正。
更新:循环中没有任何特定的逻辑,我只是做一些测试,实际上这是一个在面试中提出的问题,面试官提示我改变循环的顺序以获得更好的性能。顺便说一句,我使用的是JDK1.5。经过一些测试我现在比较困惑,因为程序的结果不一致---有时候第一个循环比第二个循环运行得快,但大部分时间它的运行速度比第二个慢。答案 0 :(得分:6)
编辑:原始答案如下。现在您已经修复了示例以便所有循环变量从0开始,我们又回到了没有足够的信息。似乎可能它是参考问题的缓存一致性/局部性 - 但我们只是在猜测。如果你能提供一个简短而完整的程序来证明这个问题,那将会有所帮助......就像告诉我们我们正在谈论的语言/平台一样!
第一个循环有10 * 999999 = 9999990次迭代。第二个循环具有1000000 * 9 = 9000000次迭代。因此,我希望期望(所有其他条件相同)第一个循环需要更长的时间。
但是,您还没有说明您正在做什么工作或者这是什么平台。有很多事情可能会影响事情:
答案 1 :(得分:4)
这个答案是针对更新的问题:
int[][]
等二维数组,则内循环中值较大的数组应该较慢。不是很多,但仍然。要稍微了解这个问题,请阅读Joel博客文章中的Shlemiel the street painter。Long
对象而不是long
原语只是愚蠢的,JVM很可能通过用原始代替它来优化它,如果它可以,如果它不能,则必然会是一些(虽然非常轻微)使用它不断减速。答案 2 :(得分:2)
因为你在第一个例子中做了大约100万次的工作。 ; - )击>
答案 3 :(得分:2)
如果查看生成的字节代码,两个循环几乎相同。除了它为10循环执行while条件之外,Java从指令中获取10作为立即值,但是当它为1000000循环执行while条件时,Java从变量中加载1000000。我没有关于执行每条指令需要多长时间的任何信息,但似乎立即加载比变量加载更快。
请注意,在第一个循环中,与1000000的比较必须进行1000万次,而在第二个循环中,它只进行了100万次。当然,在第二个循环中,与10的比较更为常见,但如果变量负载比立即负载慢得多,那么这将解释您所看到的结果。