I had an argument with my friend regarding this.
Consider the below snippet,
for(i=0; i<someList.size(); i++) {
//some logic
}
Here someList.size() will be executed for every iteration, so it is recommended to migrate this size calculation to outside(before) the loop.
Now what happens when I use an extended for loop like this,
for(SpecialBean bean: someBean.getSpecialList()) {
//some logic
}
Is it necessary to move someBean.getSpecialList() to outside the loop?
How many times will someBean.getSpecialList() execute if I were to retain the 2nd snippet as it is?
Repeated calls to
list.size()won’t result in any performance penalty. The JIT compiler will most probably inline it and even if it doesn’t, it will still be quite inexpensive because it just involves reading the value of a field.A much more serious problem with your first example is that the loop body will have to involve
list.get(i)and for aLinkedList, acessing the i th element has O(i) cost with a quite significant constant factor due to pointer chasing, which translates to data-dependent loads on the CPU level. The CPU’s prefetcher can’t optimize this access pattern.This means that the overall computational complexity will be O(n2) when applied to a
LinkedList.Your second example compiles to iteration via
Iteratorand will evaluatesomeBean.getSpecialList().iterator()only once. The cost ofiterator.next()is constant in all cases.