2

I run this code and get run time for both loop blocks. the interesting thing is that when I set the upper bound for j 2 the run time for each block is ~3500ms but when I run it with upper bound for j 10, the run time is <10ms. fast code:

        long start = System.currentTimeMillis();
        int a = 10;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < 1; k++) {
                    a += 2;
                }
            }
        }
        long finish = System.currentTimeMillis();
        System.out.println(finish - start);

        start = System.currentTimeMillis();
        a = 10;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < 1; k++) {
                    a = a + 2;
                }
            }
        }
        finish = System.currentTimeMillis();
        System.out.println(finish - start);

slow code:

        long start = System.currentTimeMillis();
        int a = 10;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 1; k++) {
                    a += 2;
                }
            }
        }
        long finish = System.currentTimeMillis();
        System.out.println(finish - start);

        start = System.currentTimeMillis();
        a = 10;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < 2; j++) {
                for (int k = 0; k < 1; k++) {
                    a = a + 2;
                }
            }
        }
        finish = System.currentTimeMillis();
        System.out.println(finish - start);

Why 10 runs faster than 2?!

Rahim Dastar
  • 1,259
  • 1
  • 9
  • 15
  • 3
    I just wonder if this is a problem with micro-bechmarking here – Eugene Sep 13 '18 at 07:25
  • how many times have to run those code? are those time mean or is that a "just one run" measurement? – jhamon Sep 13 '18 at 07:26
  • In every run I get the same result – Rahim Dastar Sep 13 '18 at 07:28
  • Can be that the compiler unpacks your loops? – TungstenX Sep 13 '18 at 07:29
  • May be! if j loop upper bounf is greater than 10 :D – Rahim Dastar Sep 13 '18 at 07:34
  • I have a theory. I guess at some point optimization is triggered so the meaningless code is removed. In your example this loop does nothing: for (int k = 0; k < 1; k++). To prove this you must look at the generated bytecode when j =2 and when j=10. I think because your outside loops iterates a lot (until Integer.MAX_VALUE -1) then it is very important what happen inside. I do not have time to investigate but you can compare the bytecode. For more information look here: https://stackoverflow.com/questions/3315938/is-it-possible-to-view-bytecode-of-class-file – Level_Up Sep 13 '18 at 08:25

1 Answers1

2

Its because JIT compiler that optimizes code on runtime.

So when you pass only 2 times, optimalization wont be as good as after 10 or 100 iterations.

So basicly this microbanchmark is wrong. That is why in order to measure such execution you should

  1. Use warmup session - dry run tested code so it will get optimized
  2. Do meaningfull iterations - 1 or 2 are not that meaningfull - 1000 runs are better - and get avg time
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • 2
    I don't think this really answers why fewer iterations could ever be faster than more. It might explain why *per iteration*, over a large number of iterations, the average duration might be lower, but OP is measuring the total time. – Michael Sep 13 '18 at 07:30