3

The question is, "We might expect method3 to run faster than method2, why is that?" but I have no idea. It seems like both methods do the same amount of operations. Could someone please enlighten me?

ArrayList<Person> method2(Person x, ArrayList<Person> people){
    ArrayList<Person> friends = new ArrayList<Person>();
    for (Person y : people) if (x.knows(y)) friends.add(y);
    return friends;  
}


ArrayList<Person> method3(Person x, ArrayList<Person> people){  
    ArrayList<Person> friends = new ArrayList<Person>();  
    for (int=0; i<people.size(); i++){ 
        Person y = people.get(i);
        if (x.knows(y)) friends.add(y);
    }
    return friends;
}
err
  • 79
  • 2
  • In the real world, 99.99% of the time, the only meaningful difference between these two methods is readability. The performance difference between the 2 depends on the size of the list, and how ArrayList implements get and getItorator methods and will almost never matter; Any design choice based on class implementation will always be inherently wrong (except where you need to squeeze every iota of performance out, in which case you will most likely be coding on a lower level) – Tezra Aug 07 '17 at 18:06

2 Answers2

5

It is not so. Both methods will run at an almost identical speed.

To the extent that they will not run at exactly the same speed, two things hold:

  1. It will not make a bit of a difference in any practical scenario.

  2. You cannot really tell whether it will be method2 or method3 that will run faster.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
4

"We might expect method3 to run faster than method2, why is that?"

It may but the difference should be minimal and even not considered as an information to choose the one or the other.

These two methods perform exactly the same thing with a variance : a enhanced for the method2() and a classic for that access to the List with get(int index) for the method3().

The compiled code of method2() will result to the use of an iterator that at runtime may be a little more long to execute but it should really not have a significant difference.


For example : hasNext() Iterator for an ArrayList performs some checks and some very minor computations :

public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}

Afor that uses the get(int index) method has less computation :

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • I think the question is asking the student to recognize that `method2()` allocates an iterator, but with modern JIT optimization and the like, doing so simply doesn't slow things down in any significant way. – Silvio Mayolo Aug 07 '17 at 17:58
  • @Silvio Mayolo You are right about the pedagogical question. Now the compiled code with iterator performs more computations. I updated to show it. These are extremely minors but these are more than `get()` method. Personally, I could not affirm that the JVM has zero processing for them after optimizations. – davidxxx Aug 07 '17 at 18:08
  • @davidxxx you are right, but in this case it will apply only if will use people.size() only single time and assign the value to a variable (you dont need to call size() for every item). – Vasile Bors Aug 07 '17 at 18:37
  • @Vasile Bors for size() you are right. I referred to `ArrayList.get()` used in `method3()` VS `ArrayList$Iterator` performance used in `method2()` – davidxxx Aug 07 '17 at 18:49