5

Well according to some Stack Overflow question answers, I've read that using declaration of object inside the loop, is better than doing it outside of it, performance sided.

I could not understand why, because when I use the declaration inside the loop, my software uses more RAM then the one with the declaration outside of the loop.

while (true) {
    String hey = "Hello.";
}

Ram usage: 1820kb

String hey;
while (true) {
    hey = "Hello.";
}

Ram usage: 1720kb

Why people say that I should use the first loop cause its better for performance, yet it uses 100kb more from the ram?

starsplusplus
  • 1,232
  • 3
  • 19
  • 32
Artemkller545
  • 979
  • 3
  • 21
  • 55
  • 4
    I guess you are checking the memory usage with Task Manager, Use [Memory profilers](http://stackoverflow.com/questions/3927/what-are-some-good-net-profilers) and don't rely on Task Manager – Habib Jan 14 '14 at 15:13
  • 5
    They say so because your measurement is almost certainly incorrect :-) – Sergey Kalinichenko Jan 14 '14 at 15:13
  • 2
    First rule of taking measurements: You don't measure what you think you are measuring. Second rule of taking measurements: See 1st rule. –  Jan 14 '14 at 15:14
  • 9
    Who is saying that the first loop is better for performance? It's generally better for *readability* to declare variables in as small a scope as possible, but that's not about performance. – Jon Skeet Jan 14 '14 at 15:15
  • 4
    Apart from the performance part, always use the minimum scope possible to reduce complexity and avoid nasty errors. – Tim Schmelter Jan 14 '14 at 15:15
  • When I put these two code snippets into Linqpad in methods and compile them the IL is identical for both. I guess this tells us that it depends what you do with them. – Chris Jan 14 '14 at 15:16
  • `hey` will always be a local of the method and assigned to. There is practically no difference in these two code blocks. – vcsjones Jan 14 '14 at 15:16
  • @JonSkeet is it correct to assume (in this case) that the compiler will optimize the first loop to resemble the second or are they semantically identical at compiler level already (only one reference on stack and other clever things which i have no idea about)? – Gusdor Jan 14 '14 at 15:17
  • 5
    Premature optimization is the root of all evil. Don't actually worry about it unless your profile your code and find the loop in question is actually the problem. As others have noted, the compiler is smart and will automatically do simple optimizations like this for you anyway. So go with what's readable and maintainable. – Matt Burland Jan 14 '14 at 15:22

3 Answers3

6

When running code under release mode in .NET, the two pieces of code are identical due to a compiler optimization technique called loop invariant code motion. There are a huge number of smart optimization techniques in the JIT optimizer that will 'fix' your code. Therefore you should in principle favor readability/simplicity in code over anything else.

Bas
  • 26,772
  • 8
  • 53
  • 86
  • Thank you! I know about this kind of optimization, but i really didn't know its name. –  Jan 14 '14 at 15:21
5

There's absolutely no difference between the two options. They are compiled to the identical IL code.

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34
1

Developer's point of view aside, the compiler is the only one who cares. If you put the declaration inside a block, you may make it easier for the compiler with registry allocation because it's more obvious what is the usage scope of the variable. But hey, compilers are smart today and you wouldn't make much of a difference (see loop invariant code motion mentioned by @Bas Brekelmans).

You cannot rely on simple measurement as suggested in comments. If there really is a deterministic difference between RAM usage, my guess would be that the compiler makes a different decision somewhere for the two versions, it works heuristically anyway.

To summarize, always prefer readability to optimization, especially with such low level details. The compilers does this job better than you.

Mifeet
  • 12,949
  • 5
  • 60
  • 108