0

In a program where I have, say, 50 for loops that run every so often; there are 50 ints being created every time they are run and then consuming memory for each of them.

If I declare an int i at the beginning of every class and then reuse it in each for loop, there would now be, say, 5 ints i (i = number of classes) created and then reassigned a value of 0 in each loop, saving space by not flooding the heap with is.

Would that help the program's performance or it just wouldn't be too much of a difference? Does heap memory works as I think it works in this case?

bcr
  • 950
  • 8
  • 28
c3r38r170
  • 25
  • 1
  • 10
  • 1
    They are not on the heap. – tkausl Apr 06 '18 at 00:38
  • 2
    Potentially saving two hundred bytes (50 ints times 4 bytes each) of memory? Ummm... maybe. Prefer which ever way is most readable. – Elliott Frisch Apr 06 '18 at 00:39
  • What language are you thinking of when you say this? (The tags suggest Java, but I want to make sure.) –  Apr 06 '18 at 00:41
  • 50 loops? Perhaps create a method with one loop and one int and then call that method 50 times. – DevilsHnd - 退職した Apr 06 '18 at 00:44
  • 1
    The space taken up by 50 ints is so small it is irrelevant. The ints are on the stack not the heap and no it wont have any performance impact. – bhspencer Apr 06 '18 at 00:45
  • Thank you all for your answers. Sorry for messing up with the heap and the stack and yes, I'm using Java. – c3r38r170 Apr 06 '18 at 00:51
  • 1
    It's always best to limit the scope of your variables, therefore unless this is causing you *serious* performance issues, declare each int within it's respective loop. Avoid premature optimisation. – Zippy Apr 06 '18 at 01:32
  • @Zippy Thanks, I know micro-optimizing is almost useless but I thought it could be helpful for future similar problems. Limiting the scope of variables is just a good practice or has another purpose? – c3r38r170 Apr 06 '18 at 01:54
  • I would say it makes code a lot simpler and less error prone. If you have an int that is available to the whole method (or class) used as the counter for multiple for-loops, then it's possible that the int may be unintentionally altered at some place and then you go into the loop with a value other that the value you expect. Or you may not reset the value after exiting a loop, so the next loop again starts with an unexpected value. If you limit the scope of the ints to each loop then this can't happen and makes the code a lot easier to work with - good luck! :-) – Zippy Apr 06 '18 at 02:05
  • @Zippy Thank you very much! – c3r38r170 Apr 06 '18 at 02:12
  • Proper microoptimizations go the other way round. Make small methods and narrow every scope - that's what gives the compiler the best starting point. At the same time, this is also best for humans. Never write harder-to-read code without a good reason. Measure before optimizing. Learn [JMH](http://openjdk.java.net/projects/code-tools/jmh/) as naively written microbenchmarks in Java produce nonsense only. – maaartinus Apr 06 '18 at 21:20

3 Answers3

1

Reusing simple, small, short living ints for multiple loops is a code smell - don't do it.

If your loops are in the same method, many loops might be a code smell on it's own. Probably you should split the method into smaller chunks of code which can be more easily tested, independent from each other.

Counters in loops are almost always independent from each other. An exception might be a loop which counts up and the next one is counting down, where the initial value is depending on the last value of the former loop. If you reinitialize your counter as the very first statement of a for loop, which is the case for 99% of the loops I have seen so far, they are independent from each other and the declaration of the counter variable should reflect that. It's an important kind of documenting your code.

Reusing a counter only documents that there are some coders with wrong ideas of optimization.

Now the worser idea is to define some counters on class level (some, because you have nested loops) and call the same counter from different methods. Wow! You woulnd't consider that, would you? That would not only avoid making the class thread save - you couldn't call one method from another one without shooting yourself into both feet.

Think of the case where you have a method with a for loop, which you are going to refactor for some reason. Maybe a more elegant solution is possible with Java9, but it has a for-loop with some i, and the i is initialized at the top of the for loop for (i=0; ... and now you look where it is coming from, and realize, it is not declared in that method, but an instance variable! And the class is 500 lines long with, let's say 20 methods, each on average 25 lines long. Many of them using that same i. Now you have to investigate, which method is called by your method, which method calls your method and might depend on the value of i which you end with, which can be run in parallel. You're doomed! Instead of 25 lines of code, you have to have 500 lines of code in your head, to reason about, what is going on.

The scope of local variables should be as narrow as possible, as long as there is no good reason to reuse it. The less lines a variable is in scope, the easier it is to understand some code.

You have always to look where a variable is initialized to find it's current value, where it is declared, to find it's type (is it a long, an int, a byte, a short?), where it is reused later. Counters are almost never reused. Make it easy to reason about your code by declaring them just in the for loops head, so everybody knows, it has no influence on later code.

Well, and use the simplified for loop where it makes sense, to prevent the ugly off-by-one errors. Then you don't have to reason about a few bytes being used.

But in the end, I admit, for a beginner, it is a reasonable question to come up with. I had the idea in former times, too. :)

Community
  • 1
  • 1
user unknown
  • 35,537
  • 11
  • 75
  • 121
0

I don't see why you'd need to have that many loops in your main method. If those integers are only being used as iterators and you really have that many loops in your program you should probably arrange them into specific functions/methods to perform whatever tasks these loops are doing.

By doing so you'd have local variables being used as iterators for each one of those methods and the memory used up for these variables would be freed up when the method finishes it's execution.

Janilson
  • 1,042
  • 1
  • 9
  • 23
  • Could you show a little example? I am not sure if I get what you mean. – c3r38r170 Apr 06 '18 at 00:54
  • In your post you talk about creating a an int i for each class (so, create an iterator as a class variable), but unless you class is a collection of objects it makes more sense to create the int i inside a method (so, as a local variable) and execute the loop you want to execute inside the method, cause then whatever memory is being used by the integer becomes reusable once the method finishes executing. I'm not sure how to give you an example because I don't really understand what you mean by a loop for each class. – Janilson Apr 06 '18 at 01:04
0

No it doesn't matter really as compilers these days are very powerful and the difference is negligible, but the main issue here is do you really need to set 'i' value on top, as your code grows and you start using 'i' in different/complex scenarios you might start seeing 'i' behaving differently and will have no clue why its happening and its pain to debug the whole thing to find what caused the issue

If you really want to know the difference you can refer to this link which talks about almost the same scenario your talking about Difference between declaring variables before or in loop?

rohit thomas
  • 2,302
  • 11
  • 23