0

I ran this segment of code: (outer loop runs 100 times, inner loop runs 1 billion times.)

long l = 0;

for(int i = 0; i < 100; i++)
    for(int j = 0; j < 1000000000; j++)
        l++;

System.out.println(l);

This took around 11-12 seconds when I ran it.

Then I ran this segment of code:

long l = 0;
int i = 0, j = 0;

for(; i < 100; i++)
    for(; j < 1000000000; j++)
        l++;

System.out.println(l);

and this took about 100 ms (0.1 seconds) whenever I ran it.

Does anyone have any idea why there's a big difference? My theory is that for every value of 'i', the inner for loop has to initialize j again, which gives it more operations to do, so it makes sense that it takes longer. However, the difference is huge (by about 100 times), and with other similar tests, the same thing doesn't happen.

If you want to see it yourself, this is how I timed it:

class Main {
    static long start, end;
    public static void main(String[] args) {
        start();

        long l = 0;
        int i = 0, j = 0;

        for(; i < 100; i++)
            for(; j < 1000000000; j++)
                l++;

        System.out.println(l);

        end();
        print();
    }

    public static void start() {
        start = System.currentTimeMillis();
    }

    public static void end() {
        end = System.currentTimeMillis();
    }

    public static void print() {
        System.out.println((end -  start) + " ms.");
    }
}
David
  • 29
  • 4
  • You could check the iterations from value of `l`. It would be 100 times less for second function. – Vikas Apr 11 '20 at 05:20
  • Not really related to your question, but since you are attempting to perform what is known as benchmarking, do you know about [Java Microbenchmarking Harness](https://openjdk.java.net/projects/code-tools/jmh/) ? – Abra Apr 11 '20 at 05:21

5 Answers5

4

The second function only iterates through j for the first iteration of I. At that point j exceeds the limit of the for loop and is never run again as it is not reset on the next iteration of i

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Oli Folkerd
  • 7,510
  • 1
  • 22
  • 46
1

In your first example, inner loop is running from 0 to 1000000000 for each value of i because we are initializing j=0 for each value of i.
In your second example, inner loop is running from 0 to 1000000000 only for i = 0 because here we are initializing j=0 only for the first iteration of the outer loop (i.e i=0).

Tarun
  • 3,162
  • 3
  • 29
  • 45
1

Real reason is in second case loop is not running as same as first code.

In first code every time you go inside you start j. With 0 But in second code j will be 1 billion in first iteration. After that It always be 1billoin. Which means second loop condition is failing every time. Second loop will not run more than once.

0

The two versions are not "almost exactly the same". In fact, they are completely different.

The clue is that they print different values for l:

/tmp$ java Main1.java
1000000000
12 ms.

/tmp$ java Main2.java
100000000000
857 ms.

Clearly one version is doing 100 times more iterations than the other. @Oli's answer explains why.


My theory is that for every value of i, the inner for loop has to initialize j again, which gives it more operations to do, so it makes sense that it takes longer.

Nope. That would not explain a 100 times performance difference. It is not plausible that 100 initializations of an int variable would take (on my machine) 800+ milliseconds.

The real explanation is that you are comparing computations that are NOT comparable.

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

j is set to 0 outside it's for loop. It is never reset back to 0 on i's next iteration.

Dizzy
  • 448
  • 5
  • 15