Cote Mounyo
Cote Mounyo

Reputation: 13965

how does compiler handle size method in for loop

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

Answers (6)

hmitcs
hmitcs

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

Rob
Rob

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

cvsr.sarma
cvsr.sarma

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

Christian Kuetbach
Christian Kuetbach

Reputation: 16060

You should ask yourself some questions:

  • Do I have a perfomance problem?
  • Have I profiled the bottleneck to this code?

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

cvsr.sarma
cvsr.sarma

Reputation: 909

int count = list.size();
for(int i=0; i<count;i++){...}// Is faster

Upvotes: 0

Brian Kocoloski
Brian Kocoloski

Reputation: 61

Any decent compiler will compile these to the exact same assembly code.

Upvotes: 0

Related Questions