Reputation: 9636
Is there any performance cost for declaring a new variable in the next case:
This is an example just to demonstrate the point.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
And I have the next method:
Option 1:
public void MyMethod(Person person)
{
if (person.FirstName.Contains("Ro") || (person.LastName.StartsWith("A") && person.Age > 20))
{
//Do something
}
else if (person.FirstName.Contains("Ko") || (person.LastName.StartsWith("B") && person.Age >= 40))
{
//Do something
}
else if (person.FirstName.Contains("Mo") || (person.LastName.StartsWith("C") && person.Age > 60))
{
//Do something
}
else
{
//Do something
}
}
Option 2:
public void MyMethod(Person person)
{
string firstName = person.FirstName;
string lastName = person.LastName;
int age = person.Age;
if (firstName.Contains("Ro") || (lastName.StartsWith("A") && age > 20))
{
//Do something
}
else if (firstName.Contains("Ko") || (lastName.StartsWith("B") && age >= 40))
{
//Do something
}
else if (firstName.Contains("Mo") || (lastName.StartsWith("C") && age > 60))
{
//Do something
}
else
{
//Do something
}
}
Again, this is just an example to demonstrate the idea of the question.
The question: Is there any performance or memory issues between option 1 and option 2?
For sure, option 2 is looking better and is more readable.
Upvotes: 2
Views: 196
Reputation: 941317
This is tackled by the jitter, it aggressively eliminates local variables of a method and looks for ways to store them in a CPU register instead. It does this whether or not you declare the variable yourself. Your property getters are simple and have no side-effect, something the jitter can find out by itself. Those getter methods are eliminated as well, they are inlined. In effect, it will transform your code from the 1st snippet to the second snippet.
This is the core reason that you cannot find out what local variables a method has through Reflection. And why you have a problem debugging optimized code. And why the volatile keyword exists in C#. A local variable simply doesn't exist anymore when the jitter optimizer is done with it.
You'll find an overview of the kind of optimizations performed by the jitter in this answer.
So, no, don't hesitate to make your code more readable this way, it is not expected to have any perf impact. Do keep in mind however that you can introduce a bug in your code doing this, it will trigger when the rest of your code affects the object you are using. You'll of course store a stale value of the property. This is not always that obvious if the class is non-trivial and the property getter has side-effects itself. Otherwise the core reason that coding guidelines in .NET demand that properties with side effects should be methods instead.
Upvotes: 8
Reputation: 244722
Meh, I find option 1 more readable. Option 2 implies that you're manipulating the values of those properties. It takes a second or two of parsing the code to figure out that you're not.
So it's just a stylistic choice. Consult your style guide to see which is preferred by your organization or particular code base.
The performance difference will be exactly nil. You probably won't trust me on this, and if not, the only way to be sure is to actually benchmark it for yourself. But that's really a waste of time.
A property getter should (unless the documentation specifies otherwise) have constant-time execution, so querying the value of the property should be no different than querying the value of a local variable. So the only other thing that could possibly impact performance is that, with option 2, you could possibly end up querying the value of all the properties, when your code might never get to the branch that requires the last name or the age. But that's probably going to be highly variable. You can really only determine this by repeated benchmarking with some real-world data. And don't waste your time unless this method is really proven to be a bottleneck. And it won't be.
If you're going to make a decision on some basis other than readability, it would be thread-safety. If the value returned by a property getter can potentially change after another thread modifies the object, then you might have a problem using Option 1. That would make caching the value of those properties into local variables more desirable, thus you'd choose Option 2.
But that is precisely why the compiler is not going to do any type of caching, turning Option 1 into Option 2, as some of the other answers suggest. The generated code will be different, the performance difference just won't be significant. (Although the JITter may certainly perform this type of optimization at run-time, as Hans points out in his answer.)
Upvotes: 6
Reputation: 36300
In practice there will be no difference in performance, I doubt you would be able to measure any difference even if you ran the code a billion times.
With that said, there is a difference. A property get operation is in fact a method call, so the first operation will call the person.get_FirstName method when you access the property. This means that there may, depending on how the compiler optimizes your code, be some difference in how your code behaves.
So there will not be any measurable difference and you should go for the most readable option. :-)
Upvotes: 0
Reputation: 13
Complexity of both is same. So i think both are equal in both regards.
Upvotes: 0