In my java program, I have a for-loop that looks something like this:
ArrayList<MyObject> myList = new ArrayList<MyObject>(); putThingsInList(myList); for (int i = 0; i < myList.size(); i++) { doWhatsoever(); }
Since the size of the list does not change, I tried to speed up the loop by replacing the loop termination expression with a variable.
My idea: since the size of an ArrayList can change during iteration, the termination expression should be executed every loop of the loop. If I know (but the JVM does not), its size will remain constant, using a variable can speed up the process.
ArrayList<MyObject> myList = new ArrayList<MyObject>(); putThingsInList(myList); int myListSize = myList.size(); for (int i = 0; i < myListSize; i++) { doWhatsoever(); }
However, this solution is slower, slower; also makes ending myListSize doesn't change anything! I mean, I could understand if the speed did not change at all; because maybe the JVM just found out that the size does not change or optimize the code. But why is it slower?
However, I rewrote the program; Now the size of the list changes with each cycle: if i%2==0 , I delete the last element of the list, otherwise I will add one element to the end of the list. So, now the operation myList.size() should be called at each iteration, I guessed.
I donβt know if this is really correct, but still the termination expression myList.size() is faster than using only the variable, which remains constant all the time as the termination expression ...
Any ideas why?
Edit (I'm new here, I hope it will be how to do it) The whole test program looks like this:
ArrayList<Integer> myList = new ArrayList<Integer>(); for (int i = 0; i < 1000000; i++) { myList.add(i); } final long myListSize = myList.size(); long sum = 0; long timeStarted = System.nanoTime(); for (int i = 0; i < 500; i++) { for (int j = 0; j < myList.size(); j++) { sum += j; if (j%2==0) { myList.add(999999); } else { myList.remove(999999); } } } long timeNeeded = (System.nanoTime() - timeStarted)/1000000; System.out.println(timeNeeded); System.out.println(sum);
Published code performance (average 10 executions): 4102ms for myList.size () 4230ms for myListSize
Without if-then-else instructions (therefore with a constant size of myList) 172ms for myList.size () 329ms for myListSize
Thus, a speed different from both versions still exists. In the version with if-then-else parts, the percentage differences are, of course, less, because a lot of time is invested in the operations of adding and deleting the list.