-1

I have read some questions and answers about this problem, like this, this, and this. Most of them say for-each it not slower than for, and even faster in some case.

But I write the following code and the result make me confused.

  public ForWithArraylist() {
    // TODO Auto-generated constructor stub
    for (int i = 0; i < 1000000; i++) {
        number.add(i);
    }
    now = System.currentTimeMillis();
    second = 0;
    third = 0;
}
public void random() {
    for (int i = 0; i < number.size(); i++) {
        int j = number.get(i);
        //second = j;
    }
    second = System.currentTimeMillis();
    System.out.println(second - now);
}
public void it() {
    for (Iterator<Integer> iterator = number.iterator(); iterator.hasNext();) {
        int i = iterator.next();
        //third = i;
    }
    third = System.currentTimeMillis();
    System.out.println(third - second);
}
public void each() {
    for (Integer num : number) {
        int i = num;
    }
    System.out.println(System.currentTimeMillis() - third);
}

I run it on windows(jdk 6), one of the results is:

(The time is for, iterator and for-each respectively). On average, 'for' is faster the other two about 25 ms.

I run it on MacBook, one of the results is:

(The time is for, iterator and for-each respectively). On average, 'for' is the same as for-each or even slower and iterator is slowest.

So could anyone explain it to me?(the ide, or operating system, or something else)

Edit: Thanks for the reminder of weston, I run it on the another windows (jdk 7), and I have the similar result with MacBook.

Community
  • 1
  • 1
Tony
  • 5,972
  • 2
  • 39
  • 58
  • 3
    For one thing, you can't base a finding on a single test, but you have to run a whole battery of tests. – AntonH May 06 '14 at 12:56
  • 5
    [Micro-benchmarks](http://www.ibm.com/developerworks/java/library/j-benchmark1/index.html) like this will likely lead you astray. Also, lies, damned lies and [statistics](https://www.ibm.com/developerworks/java/library/j-benchmark2/). – Elliott Frisch May 06 '14 at 12:57
  • If you want more definitive insights you might want to construct loops that all use `Integer`, then check the byte code. – keyser May 06 '14 at 12:59
  • @AntonH I run it many times. I just showed one picture. – Tony May 06 '14 at 13:03
  • @keyser Could you explain it more explicitly? – Tony May 06 '14 at 13:08
  • [Like this](http://stackoverflow.com/a/2113226/645270) – keyser May 06 '14 at 13:10
  • 1
    JDK 1.6 and JDK 1.7. I know the enhanced for loop uses array accesses, http://stackoverflow.com/a/1006425/360211 but maybe it also does that for array accesses from 1.7. – weston May 06 '14 at 13:13
  • @weston Thanks for your reminder and sorry for being so late to response. – Tony Jul 06 '14 at 09:06
  • 1
    possible duplicate of [How do I write a correct micro-benchmark in Java?](http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) – Raedwald Jul 06 '14 at 10:24

1 Answers1

3

You shouldn't use currentTimeMillies() to measure CPU execution times because this method has unexpected delays and is also less accurate. You should use System.nanoTime() because first, it goes by nano seconds, secondly, its value is update more frequently.

Further more, you shouldn't conclude anything from running this time measurement just once. You should do it few times and calculate the average. The operation system has other business to take care of and it isn't realtime system.

Lastly, you must make sure you are doing absolutely the same thing in all loops. Calling the method "add" on array list does much more than assigning a value to a position in array.

Elad Lavi
  • 633
  • 5
  • 7