Reputation: 13965
which of the following two snippets is faster, assuming list
is an ArrayList.
for(int i=0; i<list.size();i++){...}
or
int count = list.size();
for(int i=0; i<count;i++){...}
Also, does the optimization (if any) carry to Android's ArrayAdapter?
int sCount = mAdapter.getCount();
CLARIFICATION
in the for-loop does the compiler call list.size()
each time or does it call it once and use it subsequently.
Note that each call to list.size()
will actually go and count the items. So that's the essence of the question.
Upvotes: 2
Views: 225
Reputation: 387
I think the second piece of code is slightly faster. A method call may need to load code into memory and will load data from and to the method memory stacks (as in the first piece of code). Which is obviously, slower than a single memory access (first piece of code). However, I think it's safer to use the first piece of code, if the array size may change during the loop iterations. Consider the following example:
for(int i=0; i<list.size();i++){
if list.get(i) == 0 { list.remove(i); i--; }
}
The example above remove null elements from the array. Thus, the array size decreases each time an element is deleted. If you don't use list.size() and forget to appropriately update the size of the array, you will end up with "index out of bound" exception.
Upvotes: 0
Reputation: 6497
In most situations, the speed will be indistinguishable. That said, your two loops are semantically different if the collection might be changing while the loop is executing. The modification of the collection could be in the loop (or in code called in the loop) or in a different thread that is executing concurrently.
To specifically answer your "clarification": yes, the size
method will be invoked each time through the loop.
I would never write the "optimized" version of this loop unless I had clear evidence that the optimization was important to do (and the collection isn't changing). If your code is so tuned that such tweaks are giving you measurable speedups, you should be pretty happy.
Upvotes: 3
Reputation: 909
ArrayList list = new ArrayList();
for(int i=0; i<1000000;i++){
list.add("Object added "+i);
}
long startTime =System.currentTimeMillis();
for(int i=0; i<list.size();i++){
System.out.println(list.get(i));
}
long endTime = System.currentTimeMillis();
int count=list.size();
long startTime1 =System.currentTimeMillis();
for(int i=0; i<count;i++){
System.out.println(list.get(i));
}
long endTime1 = System.currentTimeMillis();
System.out.println("Exe1 time in millis secs"+(endTime-startTime));
System.out.println("Exe2 time in millis secs"+(endTime1-startTime1));
OutPut
...........
.............
Object added 999999
Exe1 time in millis secs14131
Exe2 time in millis secs14106
Upvotes: 0
Reputation: 16060
You should ask yourself some questions:
If booth questions can be answered wit YES, than try both ways and profile the results.
In fact I think it just won't make a difference.
Upvotes: 2
Reputation: 909
int count = list.size();
for(int i=0; i<count;i++){...}// Is faster
Upvotes: 0
Reputation: 61
Any decent compiler will compile these to the exact same assembly code.
Upvotes: 0