我编写了以下代码来测试java执行从0到大数的简单任务需要多长时间:
public static void main( String[] args )
{
for( long k = 0 ; k <= 1000000000000000000L /* 18 zeros */ ; k++ )
;
System.out.println( "Finished" );
}
我运行程序并等了几个小时。等了这么久以后我除了参考一些计算来估计这个运行时间之外别无他法,并且通过一个简单的计算我确信程序最终可能需要超过100年(取决于CPU)才能最终打印消息“完成”!
但是在尝试下面的代码看起来花费的时间与上面的代码完成时,我意外地看到在运行程序后,在几分之一秒内打印出“已完成”的消息!
public static void main( String[] args )
{
int j;
for( int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++ )
for( j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++ )
;
System.out.println( "Finished" );
}
java的行为与这两段代码的区别是什么? java的行为与int数字之间必然存在一些差异,并且其行为与int以外的整数类型相同。
答案 0 :(得分:0)
实际上我认为这是编译器的编译器优化技术。我不认为它是&#34; Java Behavior&#34;,它是我们正在讨论的特定Java编译器的行为。
Java语言规范中指定了Java自己的行为,for-loop specification没有指定int
或long
类型变量的优化。
对于现任&#34;官方&#34;编译器,它可能会或可能不会在将来优化long
类型的增量变量。
--------------------------------优化实验
我运行了以下两个程序:
计划1(永远运行):
public static void main( String[] args )
{
long counter = 0L;
int j;
for( int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++ )
for( j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++ )
counter++;
System.out.println( "Finished" + counter);
}
计划2(立即结束):
public static void main( String[] args )
{
long counter = 0L;
int j;
for( int i = 0 ; i <= 1000000000 /* 9 zeros */ ; i++ )
for( j = 0 ; j <= 1000000000 /* 9 zeros */ ; j++ )
counter++;
System.out.println( "Finished");
}
因此,编译器检测嵌套循环外是否有任何可见的变化,如果没有,它基本上会跳过内循环。