Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Near empty Java For-Loop acts strange

This code acts as expected printing "Average Number of Runs: 0.99864197"

import java.util.Random;

public class A {
    public static void main(String[] args) {
        int min = -30;
        int max = 1;
        test(min, max);
    }
    static void test(int min, int max){
        int count = 0;
        Random rand = new Random(0);
        for(int j = 0; j < 2097152; j++){
            int number = min + rand.nextInt(max-min+1);
            for(int i = 0; i < number; ++i) {
                System.out.print("");
                count++;
            }
        }
        System.out.println("Average Number of Runs: " + count/65536F);

    }
}

This code that should print the same exact number, but instead it prints a random negative number.

import java.util.Random;

public class A {
    public static void main(String[] args) {
        int min = -30;
        int max = 1;
        test(min, max);
    }
    static void test(int min, int max){
        int count = 0;
        Random rand = new Random(0);
        for(int j = 0; j < 2097152; j++){
            int number = min + rand.nextInt(max-min+1);
            for(int i = 0; i < number; ++i) {
                //System.out.print("");
                count++;
            }
        }
        System.out.println("Average Number of Runs: " + count/65536F);

    }
}

Is there some optimization that happens in java for loops?

Notes:

  1. I'm using jdk1.6.0_45.
  2. In normal usage the new Random would have a better seed.
  3. min and max should be able to be any number.
like image 382
Zaide Chris Avatar asked Nov 13 '22 00:11

Zaide Chris


1 Answers

I believe this to be a bug in the JIT handling of very tight loops in some versions of Java 6. It may be either bug 6196102 or bug 6357124.

Updating to Java 7 should work, although I appreciate that doesn't help much in your situation. You may find that adding a "looks like it isn't a no-op, but does something you don't care about" method call within your loop fixes the problem too. For example, you could sum all the values of i, and print that to some diagnostic log afterwards to be ignored.

like image 120
Jon Skeet Avatar answered Nov 15 '22 12:11

Jon Skeet