-2
//Option 1:
int _a;
while (_running)
{
    _a = _number;
    while (_doingWork)
    {
        //work involving a
    }
}

//Option 2:
while (_running)
{
    int _a = _number;
    while (_doingWork)
    {
        //work involving a
    }
}

EDIT: Took out option 3, I see now that it is irrelevant

Main Questions:

  1. I am trying to understand which of the above is preferable, and perhaps more specifically how performance is impacted by where you declare and instantiate the variable
  2. What if these were reference types instead of primitive value types (switch out "int _a" with "Person _a = new Person()"). How would the scenarios differ in terms of performance and which one if preferred?

Additional Questions:

  1. For primitive value types, does a constructor exist?
  2. Is there any difference in performance between instantiating a primitive and a regular value type (for example a struct)

Facts:

  • int is a primitive value type
  • "int a = new int();" is the same as "int a = 0;"
  • You can instantiate a value type without the new directive, but that means a default parameter-less constructor is called, so in the case of a struct you must have that constructor in the struct. Moreover, you then have to set each field in the struct by hand
  • "new" doesn't imply "create object on the heap" in C# - it just implies "call the constructor". For value types, that doesn't create a new object, it just initializes a new value. (ref: Jon Skeet)

EDIT 2: I found this to be of relevance, if anyone else stumbles accross this question: Difference between declaring variables before or in loop?

Community
  • 1
  • 1
Magnus
  • 6,791
  • 8
  • 53
  • 84
  • 1
    Honestly, the compiler/optimizer has the freedom to "lift" variables up and out if they're constants, so it MAY be that even though you've changed the code textually, the generated IL might be identical. – pmbAustin Aug 21 '14 at 18:46
  • Each of these 3 scenarios do different things, how can you compare them then? – Jeroen Vannevel Aug 21 '14 at 18:49
  • 1
    Of your 3 facts (the 4th one got cut off), only the first one is true. "*"int a = 100;" is the same as "int a = new int(); a = 100;"*" that is wrong,`int a = new int(); a = 100;` is the same as `int a = 0; a = 100;`. "*You can instantiate a value type without the new directive, but that means its constructor does not get called*" incorrect again, there is a constructor that you do not see which is called. – Scott Chamberlain Aug 21 '14 at 18:51
  • Sorry guys, fixed the mistakes. @ScottChamberlain, I thought with for instance structs, if you do not use new, you have to manually set every field because you did not pass values to constructor. – Magnus Aug 21 '14 at 18:56
  • @Magnus It still implicitly calls the parameterless constructor. You will get a compiler error if you try to make a struct without a parameterless constructor. – Scott Chamberlain Aug 21 '14 at 19:00
  • I have fixed the errors and added a link that could potentially help future visitors. Would appreciate it if the down-votes would be reversed or explained so I can do my best to address the issue(s). Thanks – Magnus Aug 21 '14 at 19:25

1 Answers1

2

C# creates a memory location for all variables in a function when it gets into the function. If you go through a loop, it does not reinitialize the memory location, so 1 and 2 are the exact same. As for 3, if you need it to be set every time through that loop, then that's what you need. Otherwise set it when it's appropriate. And scope things based on what their scope SHOULD be, not what you think helps performance.

Kyle W
  • 3,702
  • 20
  • 32
  • Is the memory location still the same if it was a reference type and I kept doing "_person = New Person();" over and over very quickly? – Magnus Aug 21 '14 at 19:09
  • @Magnus Both code snippets are constructing new instances of the object in each iteration of the outer loop, regardless of the scope of the variable. Your first code snippet is not creating the object once and then re-using it for each iteration of the outer loop. This makes them semantically identical. – Servy Aug 21 '14 at 19:16