5

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.
Zaide Chris
  • 361
  • 1
  • 8
  • I seem to remember that this is a duplicate, but I suspect I'll have trouble finding it. I *think* it's a JIT bug in 1.6 which was fixed in Java 7. Can you try on Java 7? – Jon Skeet Aug 04 '13 at 07:12
  • @JonSkeet I just tried this in Java 7, and this worked perfectly. – tbodt Aug 04 '13 at 07:22
  • Running the code on jre 7u25 does seem to fix the issue, so it does seem to be a bug in Java 6. That kind of sucks since a quite a handful of people in the minecraft community, seem to not know how to update and this code is part of a Game-Modification I've been working on... Also @Jon Skeet can you post an Answer so I can mark it as accepted? – Zaide Chris Aug 04 '13 at 07:38
  • @ZaideChris: Will do, although I'm not sure it's worth much as it is... – Jon Skeet Aug 04 '13 at 07:41
  • Both code versions work perfectly on java 1.6.0_26. – dcernahoschi Aug 04 '13 at 07:43

2 Answers2

2

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
-1

It works fine here on openjdk 1.7.0_25 fedora-2.3.10.4.fc19-x86_64. You should update your Java version, or ensure that your problem is actually with the code as stated.

Steven Schlansker
  • 37,580
  • 14
  • 81
  • 100