8

I wrote the following code to test how long it takes for java to perform the simple task of counting from 0 to a huge number:

public static void main( String[] args )
{
    for( long k = 0 ; k <= 1000000000000000000L /* 18 zeros */ ; k++ )
        ;
    System.out.println( "Finished" );
}

I ran the program and waited for hours. After waiting so long I had no way other than referring to some calculations to estimate this running time, and with a simple calculation I convinced that it can take even more than 100 years (depending on the CPU) for the program to finally print the message "Finished"!

But after trying the following code which appears to take just as much time as the above code to finish, I unexpectedly saw that the message "Finished" was printed in a fraction of a second after I ran the program!

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" );
}

What is the difference of java's behavior with these two pieces of code? There must actually be some difference between java's behavior with int numbers, and its behavior with integer types other than int.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
  • I'd expect both of these loops to be optimized out by the JIT compiler. It seems, however, that the loop with the long isn't being optimized for whatever reason. – FThompson Oct 02 '15 at 23:17
  • There is already a similar question in SO, but no good answer was given there. – user3437460 Oct 03 '15 at 12:28

1 Answers1

0

Actually I think it is the compiler optimization technique of the compiler. I don't think it is "Java Behavior", it is the behavior of a specific Java compiler we are talking about.

Java's own behavior was specified in Java Language Specification and the for-loop specification doesn't specify the optimization of either int or long type variables.

For the current "official" compiler, it may or may not be optimizing long type of incremental variables in the future.

-------------------------------- Optimization Experiment

I ran the following two programs:

Program 1 (runs forever):

    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);
    }

Program 2 (finishes immediately):

    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");
    }

Therefore it is the compiler that detects if there are any visible changes outside the nested loop, if there are none, it basically skips the inside loop.

Yibin Lin
  • 681
  • 1
  • 6
  • 20
  • While it's true that the loop is optimized, this doesn't answer why the loop using the long *isn't* optimized. – FThompson Oct 03 '15 at 00:11
  • @Vulcan I agree it is not known. However the optimization technique is specific to a certain version of compiler. And it is not in the Java Language Specification - i.e. the implementation of Java compiler can change any time. The optimization of `long` types may or may not come in the future. – Yibin Lin Oct 03 '15 at 00:14