1

I have the following program. I was just kind of messing around with other stuff when I noticed something unusual. The line "y = 3;" seems to have an effect on how fast the previous block of code can be run. When the line is commented out, the first half of the code runs around ten times slower than the second half. However, when the line is uncommented, both halves run at the same speed. Interestingly, the line in question should not be doing anything, as at that point the value of y is already 3.

EDIT: I added line "System.out.println(y)" right above "y=3" and it prints 3. That's why I think it's 3. And I'm measuring based on the output of the program. The two lines that it prints are the two runtimes, and the Timer code at the bottom shows clearly how I am measuring time.

/**
 * @author lpreams
 */
public class Misc {
    public static void main(String[] args) {
        new Misc().run();
    }

    public void run() {
        Timer t = new Timer();
        t.start();
        int y = Integer.MIN_VALUE;
        for (int j = 0; j < Integer.MAX_VALUE; ++j) {
            for (int i = 0; i < Integer.MAX_VALUE; ++i) {
                ++y;
            }
        }
        t.stop();
        System.out.println(t.getElapsedTime());
        t.reset();      
        //y = 3;
        t.start();
        for (int j = 0; j < Integer.MAX_VALUE; ++j) {
            for (int i = 0; i < Integer.MAX_VALUE; ++i) {
                ++y;
            }
        }
        t.stop();
        System.out.println(t.getElapsedTime());
    }

    private static class Timer {

        private long startTime = 0;
        private long stopTime = 0;
        private long elapsed = 0;

        public void start() {
            this.startTime = System.nanoTime()/1000000;
        }

        public void stop() {
            this.stopTime = System.nanoTime()/1000000;
            elapsed += stopTime - startTime;
        }

        public long getElapsedTime() {
            return elapsed;
        }
        public void reset() {
            elapsed = 0;
        }
    }
}

I am running this code in Eclipse on OS X 10.9.2. I am running the latest version of java. My machine is a MacBook Pro with a 2.4ghz Core 2 Duo with 8gb of RAM.

lpreams
  • 151
  • 6

2 Answers2

0

This is potentially JIT optimisation. If you run with the following vm argument:

-Djava.compiler=NONE

based on this stackoverflow article:

how to make sure no jvm and compiler optimization occurs

You can prevent this and should see the same result. I ran with this argument and got almost the exact same processing time.

Community
  • 1
  • 1
GoldenJam
  • 1,459
  • 1
  • 11
  • 17
  • You know you should not have done this. If you want to comment, earn some reputation – Stephen C Apr 23 '14 at 22:25
  • And how do I do that? by taking part. I'm interested in the question, and wanted to help and further the discussion. – GoldenJam Apr 23 '14 at 22:28
  • You do it by asking decent questions and writing decent (proper) answers. You won't get rep points by posting comments as answers. – Stephen C Apr 23 '14 at 22:39
0

Any results that you get from this micro-benchmark are suspect. You are not taking account of JVM warmup effects.

Having said that, if we can assume that the effect is real I would put it down to the JIT optimizer being unable to detect that the first loop body can be optimized away ... when the y = 3 assignment is there. You are running into a case where adding a bit more "complexity" is inhibiting an optimization. It happens.

(The value being assigned is immaterial. This is all to do with code generation by the JIT compiler ... which happens before the y value that you predict will be 3 can be calculated by anything. It can influence the JIT compiler's behaviour.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216