How does .NET optimise properties with operations? - c#

For discussion, I have this class with properties
public class Intresting
{
decimal _mQty, _mSpareQty;
public Qty { get { return _mQty; } set { _mQty = value; } }
public SpareQty { get { return _mSpareQty; } set { _mSpareQty= value; } }
public SparePercentage
{
get { return _mQty == 0 ? 0 : _mSpareQty / _mQty; }
set { _SpareQty = Qty * value; }
}
}
I am concern If I have 1,000,000 Interesting objects displayed in a custom GridView in a read only situation which shows SparePercentage via the property, the SparePercentage will be calculated over and over again or will there be optimised for example using a third _mSpareQtyPercentage which gets recalculated when Qty and SpareQty is set?

I very much doubt that there's anything in the JIT which would perform that optimization for you - after all, that requires more work each time Qty and SpareQty are set, and more space per object. That's not a trade-off the JIT should be doing for you. You could do that yourself, of course - just don't expect either the C# or JIT compiler to do it for you.
I would expect the JIT compiler to inline your trivial properties - which can be written as automatically implemented properties as of C# 3:
public decimal Quantity { get; set; }
public decimal SpareQuantity { get; set; }
(Note the changes to make the names more readable at the same time, by the way.)

The JIT will do nothing in particular to optimize this property and it will hence be re-evaluated in full every time it's asked for. However I doubt this would ever show up as a source of performance problems in your application. I certainly wouldn't go thruogh the troulbe of caching the result myself until a profile noted that as a problem in my application.
Note: It's also odd to have a property which has a get which is a calculation and has a set at all. When there is a calculation in the getter I usually prefer to avoid a setter entirely and instead force the caller to mutate the underlying values that are a par of the calculation

No, it will perform the calculation every time it is called. If you want to avoid that, you will have to implement your own cacheing.
.NET doesn't "optimize" properties any more than it optimizes any other functions.

This is one reason it is not recommended to put more than a getter to the backing field. If there is an operation to be performed, it should occur in a method. There is nothing in the compiler that would make an assumption about how the code should be executed.
The sample will execute the formula every time that getter is called. OT, but in a threaded environment, I would expect that the only way I could get the value would be to call a method.

Related

In C#. If a property isn't used, is it's value still calculated?

Imaginge this class
Class Person
{
public string Name { get; set; }
public int SomeExpensiveCalculation {
get {
return TimeConsumingCalulation(Name )
}
}
}
Since get is a method, I assume, when the the property "SomeExpensiveCalculation" is never requested or used, the function "TimeConsumingCalulation" is never executed. Is this correct?
That's correct. Property getter is just a method that executes when called.
But properties should be simple, avoid expensive calculations inside the property get.
That is correct. Properties are just Syntax Sugar for GetValue and SetValue function pairs. I think they also had some added reflection support.
With Time Consuming Operation for a value that may not be needed, maybe a Lazy[T] would be a good tool? It might at least be clearer that Lazy Initialsiation is your intention. Between it and WeakRefrence[T], you can usually cover edge cases with Memory allocation or time consumption.
However wich code is actually executed at runtime is a bit tricky. .NET has this Feature called a "just in time" compiler, and it may or may not do all kinds of Optimsiations. It can add a temporary variable to avoid retrieving the same collection value twice. Or cut unused temporary variables. Cut out a large part of the bounds checks in a array accessor.
Inling properties is way up there, but usually this will not affect any working of it.

C# Properties: Validation in getters or setters?

Suppose you have a private variable like so
private int _x;
And you have a property that provides external access to this variable:
public int X
{
get
{
return _x;
}
set
{
_x = value;
}
}
Is it better to put "validation" logic (value non-negative, within bounds, etc)
in the getter portion or the setter portion? It seems like it might be acceptable in either, but is there a preferred option?
The setter is preferred, for the following reason: It is better to throw and exception or display a message to the user upon inputting a garbage value, rather than allowing the garbage value, and subjecting your class to internal bad data.
You will note that the MSDN Example uses the setter for input validation.
You want your code to fail as quickly as possible, which is at the point you try to set an invalid value.
When you fail in the setter, the user knows about the problem immediately, and can fix it. If you wait until they try to retrieve the value, you are waiting too late, and the user may have no idea what went wrong, or where.
If the invalid value gets used elsewhere in the code, you are propagating bad data throughout the application, making things much worse, and even less clear to the user what went wrong.
The validation logic should be in the setter, to prevent invalid data from even reaching _x. That way, you have a useful invariant in your class: _x will always contain a valid value.
The idiomatic way to perform validation is to throw an ArgumentException or any of its subclasses when the consuming code tries to assign an invalid value to X.
Validation should be called first. If you want to use this approach you should implement your logic in set clause.
If you want create nice clean code, you should consider dedicated method for it, e.g.:
public class Test
{
public int X { get; private set; }
public void SetX(int value)
{
//... your logic, throw exception if validation failed
X = value;
}
}
Your class should keep your object in valid state.

C# check value in set accessor

How will be better in optimization goals?
public SpeedGraphModel SpeedGraphModel
{
get { return _speedGraphModel; }
set {
if (_speedGraphModel == value)
return;
_speedGraphModel = value;
}
}
or
public SpeedGraphModel SpeedGraphModel
{
get { return _speedGraphModel; }
set { _speedGraphModel = value; }
}
I think for string type will be better without checking, but for other types?
Adding another condition check instead of setting the variable value, even if it equal is redundant.
The best case if they are equal you will make 1 operation (condition).
The worst case you will make 2 operations (condition + assignment).
Instead of setting the variable no matter what. => 1 operation.
Such checking is usually used when you call some logic on the setting value (not only just set it). For instance, in desktop (WPF/WinForms) or mobile (Xamarin) you can implement your own property that behavior will be similar to the Dependency Property and call the OnPropertyChanged() method inside it. It can be used for refreshing items of the view after their updating etc. In this way, even if you set the same value to your item and then call OnPropertyChanged() it will update part of the view that can affect the performance, so you would like to make an additional check here.
If you just have a usual property, the only responsibility of which is to set value inside the private field without any logic behind, you don’t need an additional checking as it redundant and won’t increase your performance.

Performance issues when declaring variable

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.
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.
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.)
Complexity of both is same. So i think both are equal in both regards.
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. :-)

Can I remove the property setter (without ANY problem) in the example provided in the question?

In existing code of my project, at number of places the property is declared like this:
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
if (this.resourceID != value)
{
this.resourceID = value;
}
}
}
Note: private long resourceID is already declared.
Properties not only of value types but also of reference types (including string) too are declared like this.
Another example:
public Collection<Ability> Abilities
{
get
{
return this.abilities;
}
set
{
if (value == null)
{
throw new ArgumentNullException("Abilities");
}
this.abilities = value;
}
}
As per my knowledge, the setter in the first example does not make any sense and the if condition is meaningless there. So i decided to change the code (as part of refactoring) to make them Auto-Properties. (In second example I need setter since exception is handled there.)
I want to know from experts here, will whether making existing properties auto properties (or at least removing if condition from setter) cause any harm? Sometimes there are subtle things which a developer may not be aware of and some changes can have side effects too. That's why I am asking this question. (My libraries are used at many places.)
Note: Let me know if this is purely a homework question.
Converting:
private long resourceID;
public long ResourceID
{
get
{
return this.resourceID;
}
set
{
this.resourceID = value;
}
}
into:
public long ResourceID { get; set; }
won't cause any harm, guaranteed.
Removing the if statement might cause harm. For example in WPF when working with the MVVM pattern and implementing the INotifyPropertyChanged interface it is often good practice to check whether the value has changed before actually setting it. Removing this check will provoke notifications to be sent to the UI no matter whether the value changed or not. So it would be a breaking change.
I can only think of one kind of problem you could run into (which is fixable):
If you are using ORM or other external tool, they might rely on a naming convention for finding properties/fields. So, the 3rd party dll might be looking for a field resourceId that no longer exists.
So, code using reflection to access fields might break, but if you have control over the codebase, that is unlikely to be an issue.
There are some edge-cases where this might cause harm:
Changing to an automatically implemented property {get;set;}
if you are using field-based serialization at any point (for example, BinaryFormatter), then this will break when changing to an automatically implemented property, as the field-name will change. This will also impact any other scenario that uses reflection to access the (hopefully private) fields, but BinaryFormatter is the most common cause of confusion here.
Removing the if test
will be fine for most data-types such as long etc, however, if you use it with a type that implements a custom equality operation, you might find you are suddenly swapping a reference when previously (with the if) the objects reported equal for different references
The first is a more likely problem. If you are using BinaryFormatter, then keep the private field (byt maybe remove the if test). And then start refactoring your code away from BinaryFormatter ;p
What you have done is correct. The if statement is meaningless. I always think that less code is better, because the lines of code is directly proportional to the number of faults.
public long ResourceID { get; set; }
Your first example only sets the resourceID field if its value has changed.
The only difference you would see by removing the "if" test is a possible impact if multiple threads are reading the value. In which case they probably should be using a lock, so it's almost certainly safe to remove the test.
Your second example prevents a caller from setting the property value to null. Presumably the field is initialized to a non-null value, and this has value as it means that callers can read the property without needing to check for null.
Usually in such scenarios and how you've explained, it shouldn't be a concern.
You could just go ahead and change the code of all properties;
public long ResourceID { get; set; }
Or
public long ResourceID
{
get { return this.resourceID; }
set { this.resourceID = value; }
}
But it might cause an issue if upon
changing the value of the property,
it cascades to some other custom
function-call which is only executed
if the new value is different from
old ones. Usually when when you've implemented custom events or even maybe in case of property-changed events
Also might affect, when using
Data-Context classes
Both scenarios are totally application specific.
I'd suggest you reactor with caution. Or as you've written yourself, HOMEWORK.

Categories