在JAVA的嵌套循环中,为什 么小循环中的大循环比大循环中的小循环快? [重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在JAVA的嵌套循环中,为什 么小循环中的大循环比大循环中的小循环快? [重复]相关的知识,希望对你有一定的参考价值。
当迭代次数相同时,我想知道外部“ for循环”的较小迭代是否更快。
这是我的Java代码。
总循环迭代为1000亿。
public class Test
public static long run1()
final long start = System.nanoTime();
long cnt = 0;
for(int i = 0; i<1000000000; i++)
for(int j = 0 ; j<100 ; j++)
cnt++;
final long end = System.nanoTime();
System.out.println("run1 : "+(end-start)*1e-9+" sec");
return start - end;
public static long run2()
final long start = System.nanoTime();
long cnt = 0;
for(int i = 0; i<100; i++)
for(int j = 0 ; j<1000000000 ; j++)
cnt++;
final long end = System.nanoTime();
System.out.println("run2 : "+(end-start)*1e-9+" sec");
return start - end;
public static void main(String[] args)
for(int i = 0 ; i < 10 ; i++)
long test1 = run1();
long test2 = run2();
System.out.println("Time diff : "+(test1-test2)*1e-9+" sec\n");
这是结果
run1 : 4.5772473950000006 sec
run2 : 1.7155700900000002 sec
Time diff : -2.861677305 sec
run1 : 4.4107229420000005 sec
run2 : 1.6532413140000002 sec
Time diff : -2.7574816280000003 sec
run1 : 3.815836296 sec
run2 : 1.761153921 sec
Time diff : -2.054682375 sec
run1 : 3.913543021 sec
run2 : 1.752971717 sec
Time diff : -2.1605713040000003 sec
run1 : 3.851766485 sec
run2 : 1.7262416440000001 sec
Time diff : -2.1255248410000003 sec
run1 : 3.95305219 sec
run2 : 1.7323067330000002 sec
Time diff : -2.220745457 sec
run1 : 3.924869236 sec
run2 : 1.6953032440000002 sec
Time diff : -2.229565992 sec
run1 : 3.839871705 sec
run2 : 1.692300162 sec
Time diff : -2.147571543 sec
run1 : 3.93864626 sec
run2 : 1.704322469 sec
Time diff : -2.234323791 sec
run1 : 3.863758493 sec
run2 : 1.700392962 sec
Time diff : -2.163365531 sec
像这样,
我想知道为什么会出现这些结果。
并且由三重嵌套循环编辑,获得类似的结果。
简短的答案是:JIT和您的数学是错误的。
让我们开始于您的run方法,该方法以此打印行和返回值结尾
System.out.println("run1 : "+(end-start)*1e-9+" sec");
return start - end;
这里的问题是您要打印开始-结束,然后返回开始-结束。我没有在run方法中进行数学运算,而是对其进行了移位,以便每次运行仅负责运行和计时:
public class loops
public static long run1()
final long start = System.nanoTime();
long cnt = 0;
for (int i = 0; i < 1000000000; i++)
for (int j = 0; j < 100; j++)
cnt++;
final long end = System.nanoTime();
return end - start;
public static long run2()
final long start = System.nanoTime();
long cnt = 0;
for (int i = 0; i < 100; i++)
for (int j = 0; j < 1000000000; j++)
cnt++;
final long end = System.nanoTime();
return end - start;
public static void main(String[] args)
for (int i = 0; i < 10; i++)
long test1 = run1();
long test2 = run2();
System.out.println("run1 : " + test1 + " ns");
System.out.println("run2 : " + test2 + " ns");
System.out.println("Time diff : " + (test1 - test2) + " ns\n");
我也参加了数学考试,因为..那么,为什么要打扰?将值视为纳秒有什么问题?那才是真正的...
运行此命令,您会看到初始的大值减小并接近零。在某些运行中,这两个版本甚至都达到零。
零纳秒?是的,instant计算。让Quantum计算吸这一点!好吧,这不是really即时。当您检查nanoTime description时不是:
此方法可提供纳秒级精度,但不一定纳秒分辨率(即值更改的频率)
它比可测量的速度快,因为JIT可能最终发现该方法实际上没有任何作用。现在,为什么一个或另一个比另一个下降得更快,将需要更深入地研究JIT,以及JIT如何决定优化一种方法而不是另一种方法-这是我所知道的。
实际上,没有任何区别。两种方法初次运行后,最大时差最多只有几毫秒。我不认为说一个版本确实比另一个版本快要有意义。
GraalVM的性能似乎不佳...尽管,可能有一些标志可以改善它...
您看到的性能差异是由于循环展开,JVM首先展开内部循环,但无法展开外部循环。
展开表示:
for (int i=0;i<MAX;i++) cnt++;
被转换成类似:
int i=0;
for (;(i+16)<=MAX; i+=16) cnt+=16;
for (i<MAX; i++) cnt++; // handle case when MAX % 16 != 0
所以操作总数实际上是:
run1: 1000000000 * (100 / 16 + 4) = 10 000 000 000 operations
run2: 100 * (1000000000 / 16) = 6 250 000 000 operations
以上是关于在JAVA的嵌套循环中,为什 么小循环中的大循环比大循环中的小循环快? [重复]的主要内容,如果未能解决你的问题,请参考以下文章