Java 为什么在for循环内部定义变量后运算比在外部速度更快?

yzf_stu111 发布于 03/26 19:36
阅读 319
收藏 0

最近在复习for循环写了如下的代码
public void test1() {
        int res = 0;
        int n = 1;

        for(int i = 0; i < 2000000000; ++i) {
            res += n;
        }

    }
        
public void test2() {
        int res = 0;

        for(int i = 0; i < 2000000000; ++i) {
            int n = 1;
            res += n;
        }

    }


一开始我以为test2()需要不断地创建n会导致性能下降,但是测试的结果完全反了过来。

查看了字节码之后发现编译器没有做什么优化。(不是很会看)

想请问各位大神,是哪里导致速度相差这么大?
 

加载中
0
chentao106
chentao106
你使用benchmark之类的工具测试的,还是直接main函数跑的?没有预热的话,JIT对前一段代码的执行时间影响很大,你交换下调用位置试试
yzf_stu111
yzf_stu111
尝试过交换位置和两个方法单独运行,结果一样。
0
tcxu
tcxu

以下测试,以纳秒 (ns, nanosecond,时间单位。一秒的十亿分之一,即等于10的负9次方秒) 为单位记录执行楼主所示的循环体所需的时间。

  1. 开始持续地、分别调用 test1() 和 test2()、 大约 10 次 ,所记录的执行时间,显示chentao106所示的预热 现象。
  2. 之后(预热后)的记录显示, 即 调用 test1() 和 test2() 的运行时间的对比记录表明,两者没有明显的 "持续区别"。
  3. 结论:

就(以纳秒为单位的)运行时间记录而言,将有关变量定义在 for 循环体内,或定义在循环体外,两者在统计(多次反复调用测试)上看不出区别。

public class Cns{

public static void test1() {
	long startTime=System.nanoTime(); 
        int res = 0;
        int n = 1;

        for(int i = 0; i < 2000000000; ++i) {
            res += n;
        }
    long endTime=System.nanoTime();  
System.out.println("方法 test1() 运行时间:" + (endTime - startTime) + "ns");  
    }
        
public static void test2() {
		long startTime=System.nanoTime(); 
        int res = 0;
        for(int i = 0; i < 2000000000; ++i) {
            int n = 1;
            res += n;
        }
 	long endTime=System.nanoTime();  
System.out.println("方法 test2() 运行时间:" + (endTime - startTime) + "ns");    
    }
    public static void main(String args[]){
	int n =0;
	while(n++<30){
		test1();    
		test2();  
		}; 	
    }
}

 

方法 test1() 运行时间:141307567ns
方法 test2() 运行时间:2905566ns
方法 test1() 运行时间:3260377ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:68543ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:64511ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:66344ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:60846ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:366ns
方法 test1() 运行时间:366ns
方法 test2() 运行时间:367ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:367ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:366ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:366ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:366ns
方法 test2() 运行时间:367ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:367ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns
方法 test1() 运行时间:0ns
方法 test2() 运行时间:0ns

 

返回顶部
顶部