3

Supposing I need to iterate over something and set a variable in every cycle, like this:

for (int i=0; i < list.size(); i++) {
    final Object cur = list.get(i);
}

this redefines the variable everytime, so I'm concerned that that might pollute the memory.

The alternate option is to define the variable once and then reassign it every iteration, like this:

Object cur
for (int i=0; i < list.size(); i++) {
    cur = list.get(i);
}

would this be better in terms of memory? Would it make any difference? What if cur is a primitive type instead of an Object?

Don't tell me to use foreach, I need the counter, this is just a simplified example

xeruf
  • 2,602
  • 1
  • 25
  • 48
  • 5
    It doesn't make any difference you're likely to care about. – Dave Newton Nov 14 '17 at 20:22
  • 3
    You should not worry about those things, let the compilers (especially the JIT compiler) do this work. Global Code Motion will do the right thing. – Turing85 Nov 14 '17 at 20:23
  • 1
    Also see [Declaring variables inside or outside of a loop](https://stackoverflow.com/questions/8803674/declaring-variables-inside-or-outside-of-a-loop), which is more focused on code style/safety rather than performance. – azurefrog Nov 14 '17 at 20:29
  • Downvoted for lack of prior research. 4 upvotes? Seriously? – GhostCat Nov 14 '17 at 20:59
  • I searched, but apparently I didn't find the right terms for it... - It might help future searchers to find their way towards the relevant answers ;) – xeruf Nov 14 '17 at 22:06

5 Answers5

3

From a performance point of view, I would say if you need to improve this (you measured that a hot spot was here), you can choose the solution that offers best performances.

That said, I would recommend putting it inside the loop so that you cannot use it by error outside.

BTW, you'll ease debugging and readability by not having a variable that is there without knowing if it should or not be used outside the loop.

OznOg
  • 4,440
  • 2
  • 26
  • 35
  • Right, no performance difference. Big difference in code readability though, I agree with Ozn that most programmer would prefer the declaration inside the loop. – markspace Nov 14 '17 at 20:29
3

It has no effect on performance. Both are good. They turn out to be compiled to similar bytecode as pointed by this blogpost :(http://livingtao.blogspot.in/2007/05/myth-defining-loop-variables-inside.html)

Tharun
  • 311
  • 2
  • 14
0

I would recommend you use your alternate approach - declaration of a variable - primitive or object outside the loop. However, I notice in your first approach that you are declaring the object with final keyword. This should give a hint to the compiler to optimize the code in a way that the memory utilization at the run time is as less as possible. But you shouldn't rely on that. Just use your alternate approach.

VHS
  • 9,534
  • 3
  • 19
  • 43
  • No, it wouldn't. Information about `final` modifier of *local variable* will be completely lost in the compiled code. Only class members keep information about they're final after compilation. – user882813 Nov 14 '17 at 20:49
0

Seriously use whatever you want, it will have no difference. The only difference is the scope of that variable - for example it would be much simpler to reason about the variable GC when it is inside the loop - because it basically can not "escape" the loop.

Eugene
  • 117,005
  • 15
  • 201
  • 306
0

Performance of program is depend on how much time your code is taking to produce the output, and Statement/Loops/Conditions which take more time to execute it is natural that peace of code will consume more memory then other code which take less time to generate the output.

As per your code concern, 1st loop statement where you assigning final Object on every iteration is takes more time as compare to second loop statement where it assign to same object every time.

What I tried in my local linux(Ubuntu) box, 1st statement take 18 milliseconds while 2nd statement takes only 15 seconds, so I guess 2nd statement will be more appropriate.

Code which I tried locally:

import java.util.ArrayList;
import java.util.List;

public class Solution8 {

    public static void main(String[] args) {
        List<String> lis = new ArrayList<String>();

        for (int i = 0; i <= Math.pow(10, 5); i++) {
            lis.add(i + "");
        }
        long startTime = System.currentTimeMillis();
        for (int i = 0; i <= Math.pow(10, 5); i++) {
            final Object cur1 = lis.get(i);
        }
        long endTime = System.currentTimeMillis();

        System.out.println("1st : "+(endTime-startTime)); // 18 milliseconds 
        Object cur;
        long startTime2 = System.currentTimeMillis();
        for (int i = 0; i <= Math.pow(10, 5); i++) {
            cur = lis.get(i);
        }
        long endTime2 = System.currentTimeMillis();

        System.out.println("2nd : "+(endTime2-startTime2)); // 15 milliseconds
    }

}

Hope this will help.

Simmant
  • 1,477
  • 25
  • 39