0

Question:

In terms of efficiency it seems completely wrong to have to recreate an reference variable for every for loop. Is there any way to do something like:

       Item i;
       for (i : list2)

Also, does it make that much of a difference to create temporary reference variables?

See Original Code vs Old Iterator Style below:


Original Code

for (Item i : DataStore.SomeList) {
    if (someBoolean)continue;

    if (someBoolean2) 
       finalList.add(i);

    else if (someBoolean3)
        list1.add(i);
    else
        list2.add(i);
 }

 for (Item i : list1)
    finalList.add(i);

  for (Item i : list2)
    finalList.add(i);

Old Iterator Syntax

Item i;
Iterator<Item> it =  DataStore.SomeList.iterator();

while(it.hasNext())
{

if (someBoolean)continue;

if (someBoolean2) 
    finalList.add(i);

else if (someBoolean3)
    list1.add(i);
else
    list2.add(i);
}

it =  list1.iterator();     
while(it.hasNext())finalList.add(it.next());

it =  list2.iterator();     
while(it.hasNext())finalList.add(it.next());

Update

Decompiled the class using JAD. Since JAD is old it added a few casts but the differences are visible.

Decompiled For Loop

        Item i;
        for(Iterator iterator1 = list1.iterator(); iterator1.hasNext(); finalList.add(i))
            i= (Item)iterator1.next();

        Item i;
        for(Iterator iterator2 = list2.iterator(); iterator2.hasNext(); finalList.add(i))
            i= (Item)iterator2.next();

Decompiled Iterators

for(Iterator it = list1.iterator(); it.hasNext(); finalList.add((Application)it.next()));
for(Iterator it = list2.iterator(); it.hasNext(); finalList.add((Application)it.next()));
Menelaos
  • 23,508
  • 18
  • 90
  • 155
  • 1
    Have you considered looking at the byte code generated by your two examples? I think you'll [find](http://stackoverflow.com/questions/2113216/which-is-more-efficient-a-for-each-loop-or-an-iterator) they're much a like. – Elliott Frisch Feb 27 '14 at 19:40
  • Please don't prematurely optimize - locally (on the stack) created variables are one of the lesser problems in Java... :-) – Smutje Feb 27 '14 at 19:40
  • @Elliott Frisch I've decompiled code using JAD so I'm aware FORs are converted to iterators. However, I'll check whether the compiler reuses the iterators. – Menelaos Feb 27 '14 at 19:45
  • Generally the variable creation won't effect your efficiency. The algorithm used to generate your list will though. –  Feb 27 '14 at 19:48

3 Answers3

2

In terms of efficiency it seems completely wrong to have to recreate an reference variable for every for loop

Unless your application has extreme needs for speed optimization there is no drawback to creating temporary references each iteration and discarding them. The JVM is extremely good at handling these things.

does it make that much of a difference to create temporary reference variables?

No, you shouldn't concern yourself with this type of micro-optimizations, it is almost never worth the trouble. Concentrate on writing readable and clear code instead of worrying about these things. Besides, the JVM will most probably inline them if it is more efficient anyway.

Keppil
  • 45,603
  • 8
  • 97
  • 119
2

Question:
In terms of efficiency it seems completely wrong to have to recreate an reference variable for every for loop.

Wrong. Variables don't actually exist. They are an abstraction that allows you to name things. If a variable has a value that may be used in the future, it will be at an address in memory or a register. After its useful scope, the compiler may (and probably will) reuse the address or register previously used for that variable.

Is there any way to do something like:

   Item i;
   for (i : list2)

No, the variable in a fast iteration must be const, so it can't be declared beforehand.

Also, does it make that much of a difference to create temporary reference variables?

As I said, variables don't actually exist, so no, it makes absolutely no difference whether you declare a new variable or reuse an old one.

I suggest you take a compilers course, they're very enlightening on things like this.

Kevin
  • 53,822
  • 15
  • 101
  • 132
  • If we're talking about assembly/c I thought people tried to cut down on creating new variables or copying values from one register to another? My theory is quite rusty, but based on the bytecode are you sure that it doesn't make ANY difference no matter how small? I'm guessing the JIT compiler optimizes away but wondering... – Menelaos Feb 27 '14 at 20:04
  • Sure, you would want to avoid copying values around unnecessarily, but declaring a variable doesn't copy anything. There is no bytecode at all generated when you declare a variable, you're just providing a hint to the compiler. – Kevin Feb 27 '14 at 20:06
1

Java will generally handle the temporary reference variable efficiently.

I think the bigger efficiency issue when dealing with extremely large lists is separating it into separate lists and then adding them in at the end. Something below might be more efficient.

int index0 = 0;
int index1 = 0;
for (Item i : DataStore.SomeList) {
    if (someBoolean)continue;

    if (someBoolean2) {
       finalList.add(index0);
       index0++;
       index1++;
    }

    else if (someBoolean3){
       finalList.add(index1);
       index1++;
    }
    else
        finalList.add(i);
}
  • Also I should point out depending on the type of list this could be more inefficient depending on how the list handles addition in the middle versions addition in the end of the list. –  Feb 27 '14 at 19:50