Within my company we got a briefing for performance-issues. One of the points mentioned there was the access of properties because most of them are retrieved from a database. Thus querying the object itself may result in expensive calls to underlying database.
Now I wonder if there is any difference between the following two statements (considering performace at least)
MyPropertyValue value = myObject.SomeProperty ?? ...;
And
MyPropertyValue value = (myObject.SomeProperty != null) ?
myObject.SomeProperty :
...
I suppose the former is a kind of shortcut for the latter and thus also results in two queries on the property, is this true?
Thanks for ya
The first example only access the get of the property once, and the second accesses it twice.
now, if the get does a DB call EVERY time, then the first is definitely better.
Tested in LinqPad
First expression will evaluate SomeProperty only once whereas latter will evaluate twice.
So answer depends on how expensive the property is. Generally speaking properties should be cheap. If you have a property which takes a while to return you should consider refactoring it to a method instead.
If you have a more specific question, you may get a specific answer.
Related
I have a method which takes an OrderedSet X of objects of type A, and an OrderedSet Y of OrderedSets of objects of type B. (Nested)
This method then returns a new OrderedSet Z of Edges based on the two sets given.
Basically, I give the method two sets, and the method gives me back a connection much like the mathematical definition of a function.
So if I want to make a bijective connection, I would have to ensure that both sets have equal size, and I do not want null objects to be present anywhere.
The problem is, these sets are going to be arbitrarily large, and what I would like to do is this :
Ensure that nothing in these sets will ever be null
Ensure that every set has the required size
What I have done to obtain what I want :
I implemented the OrderedSet as a HashSet with extra properties, and I simply check for null elements using Contains which is O(1) (I am not entirely sure if this is a good solution)
OrderedSet refuses to add null objects, but this does not change the possibility of changing the elements within the set once they are added, and setting them to null this way
I tried taking the easy way out and nested the contents of the method in a try-catch, so if something goes wrong I simply catch the error and move on, rather than having to first validate all the data passed (Assume the sets might be very huge, there is no limitation on their size) The issue with this is that it might fail at the very end, wasting computation time
I also tried making a brute force check, so basically checking every set for nulls, including the sets within the second parameter, and also checking every single set for its correct size to be expected. This would work in theory, but I feel is impractical and surely there could be a more clever solution to this problem.
What I have considered :
I have looked into Contracts, but this article shows a significant (in my opinion) decrease in performance, although it does accomplish what I am looking for (Yet still in a hacky sort of way)
I have read about non-nullable reference types that are supposed to come out in C# 8.0, which might solve the problem of having to check for null elements, but I would still be left with the issue of having to check for all the sizes of the sets involved, each time I want to make a new connection.
My goal :
To have a readable, yet efficient solution to parameter validation.
Thank you for your time, please feel free to correct me if I have said something that is not quite correct.
Which out of the following two equivalent ways would be best for the null conditional operator in terms of primarily performance and then ease of use or clarity etc.?
This:
idString = child?.Id;
fatherName = child?.Father?.Name;
motherName = child?.Mother?.Name;
or (assuming that all local vars are null already) this:
if (child != null)
{
idString = child.Id;
fatherName = child.Father?.Name;
motherName = child.Mother?.Name;
}
Is performance even an issue?
Is performance even an issue?
Short answer: Performance about null-checks will never be an issue in a normal application. It's only a matter of readability and maintainability.
Performance:
Yes, you have 3 "explicit" checks against 1. But you must keep in mind that:
The system performs an "implicit" null-check every time you reference an object instance, as explained here, and afaik the JIT doesn't optimize null-checks at all. So in your case the rate is not just 3 against 1.
A null-check is a very (really, very) cheap operation, compared with most operations you do in a normal software flow (instance heap allocation, mathematic calculations, a linq query, graphic object rendering, string parsing, ...).
I see only a remote possibility of significant performance differences: if child or Mother or Father are not local variables or simple plain properties, but methods and properties with very long execution time. For example, a GetChild() method that takes 2 sec to execute. Can you see a realistic scenario for that? I can't. Even if that's the case, you can call GetChild() one single time and assign it to a local variable, then call child? 3 times.
Readability:
A single initial if allows to mentally separate different chunks of code. Pretend to be the reader of the code, without knowing anything else: ask yourself if is it simpler to read "if child is not null do all this operations and stuffs, otherwise just move on", or "if child is not null check the Name. If again child is not null check the Mother. If the Mother is not null get the Mother's Name. Then if again child is not null check the Father. If Father is not null... ... ... ".
Maintainability:
Aka, in this case, the DRY principle. For example, why would you repeat the null-check 3 times? Pretend that at a certain point in the future your boss asks to you a code change: it is required not only to check the nullity of a child, but also if its Id is 0 (things like that happen very frequently in any software development process). In your first code section you should correct 3 lines.
In your second code section you should correct only 1 line: the initial if.
EDIT:
For a discussion about thread-safety on the null conditional operator, see this question.
In second code example for variables will not set new values, but in first example they set as null or value from specified properties.
The ?. operator names like null-conditional operator. This operator works like:
With using ?.:
var result = someProperty?.someField;
Without using ?.:
if (someProperty != null)
result = someProperty.someField;
else
result = null;
About this operator you can read here: https://msdn.microsoft.com/en-us/library/dn986595.aspx.
It is better to use it in fluent of methods invoking. In your sample better to use second variant, because if child is null, then other actions are not perform.
if (this.UserManagmentType != UserMgmtType.NONE)
{
return (User)GetUserBaseById(userId);
}
if (this.UserManagmentType != UserMgmtType.NONE)
{
return GetUserBaseById(userId) as User;
}
I understand the difference between casts. The first if statement should throw an invalid cast exception if the cast fails, while the second will return a null.
My question is, for identical data under heavy load in a multi-threaded environment, why does the first if statement occasionally return a null, while the second if statement will always return valid data?
The other item of note is that the containing method is a WCF endpoint.
Thank you for any insight.
The answer, given the code you've posted, is: it won't.
The first snippet will return null if (and only if) GetUserBaseById returns null. The second will return null if the method's return is null or if it's not a User object. That behaviour doesn't change under heavy load.
If you're seeing different results under heavy load as you describe then I'd suggest you have a multithreading issue elsewhere in your code, and it just happens that this is where you're seeing the effects. This sort of bug can be very sensitive to external conditions, and you're not guaranteed that it will reproduce the same way each time you run (because it might be sensitive to, e.g., disk contention with other processes).
I would suggest a thorough review of the multithreaded functionality in question: the problem you're seeing is not in that line of code.
Two castings are different, and as per this article
http://www.codeproject.com/Articles/8052/Type-casting-impact-over-execution-performance-in
using as keyword is faster, and I assume this has something to do with returning value always compared to prefix casting.
However I think you need to double check how you have implement GetUserBaseById(userId) method as I suspect it might not properly implemented for multithreaded environment.
Is there a convention for whether or not to use a property to calculate a value on call? For instance if my class contains a list of integers and I have a property Average, the average will possibly change when an integer is added/removed/modified from the list, does doing something like this:
private int? _ave = null;
public int Average
{
get
{
if (_ave == null )
{
double accum = 0;
foreach (int i in myList)
{
accum += i;
}
_ave = accum / myList.Count;
return (int)_ave;
}
else
{
return (int)_ave;
}
}
}
where _ave is set to null if myList is modified in a way that may change the average...
Have any conventional advantage/disadvantage over a method call to average?
I am basically just wondering what the conventions are for this, as I am creating a class that has specific properties that may only be calculated once. I like the idea of the classes that access these properties to be able to access the property vs. a method (as it seems more readable IMO, to treat something like average as a property rather than a method), but I can see where this might get convoluted, especially in making sure that _ave is set to null appropriately.
The conventions are:
If the call is going to take significantly more time than simply reading a field and copying the value in it, make it a method. Properties should be fast.
If the member represents an action or an ability of the class, make it a method.
If the call to the getter mutates state, make it a method. Properties are invoked automatically in the debugger, and it is extremely confusing to have the debugger introducing mutations in your program as you debug it.
If the call is not robust in the face of being called at unusual times then make it a method. Properties need to continue to work when in used in constructors and finalizers, for example. Again, think about the debugger; if you are debugging a constructor then it should be OK for you to examine a property in the debugger even if it has not actually been initialized yet.
If the call can fail then make it a method. Properties should not throw exceptions.
In your specific case, it is borderline. You are performing a potentially lengthy operation the first time and then caching the result, so the amortized time is likely to be very fast even if the worst-case time is slow. You are mutating state, but again, in quite a non-destructive way. It seems like you could characterize it as a property of a set rather than an "ability" of the set. I would personally be inclined to make this a method but I would not push back very hard if you had a good reason to make it a property.
Regarding your specific implementation: I would be much more inclined to use a 64 bit integer as the accumulator rather than a 64 bit double; the double only has 53 bits of integer precision compared to the 64 bits of a long.
Microsoft's recommendation to using methods:
Use method
If calling has side effects
If it returns different values each calls
If it takes long time to call
If operation requires parameters (except indexers)
Use property if calculated value is attribute of object.
In your case I think property with implicit lazy calculation would be good choice.
Yes there is... a get accessor should not in any way modify the state of the object. The returned value could be calculated of course, and you might have a ton of code in there. But simply accessing a value should not affect the state of the containing instance at all.
In this particular case, why not calculate everything upon construction of the class instance instead? Or provide a dedicated method to force the class to do so.
Now I suppose there might be very specific situations where that sort of behavior is OK. This might be one of those. But without seeing the rest of the code (and the way it is used), it's impossible to tell.
I'm creating a repository in EF4. For one of the methods a password and username is used to verify a user. The method returns a count of users so a 0 means they don't exist and a 1 they do. Would it make much of a difference if I just returned a user object and checked it for null?
Technically the most efficient way would probably be to use the Any() extension method. If you return an object there is the cost of filling that object. If you return a count, then there is the cost of going through every record (after the where clause has been applied) and counting them. Any() should use Exists in sql, and therefore, SQL server can stop as soon as it finds the first record.
Ultimately though, I agree with the others, this isn't a place you want to start optimizing right away. Donald Knuth probably has the best quote about this:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil".
For instance, let's say you have this method return a bool and you use the Any() method. Later in the request, you might need to pull the user object out of the database (this could be something you end up doing a lot). Now, by optimizing early, you've actually increased the number of calls to the database.
HTH
well the option with Any is going to be better because EF has a high cost of materialization and change tracking for an object and if that object happens to have lot of properties, you should definitely consider using Any.
The second version would be better - in terms of design. In terms of microefficiency it shouldn't matter
Hoakey if you want to know the truth. Both methods are going to be so negligible that it wont matter which one you choose. Choose whichever method makes your code easier to understand and read. Often times people get worried about performance in all the wrong places.
I agree with Armen, return the object and check for null. Very simple and is easy to understand what is going on.
If you don't need any data from the 'user' table after you verify that a valid user/password combo exists, then either method will work (and performance won't matter).
On the other hand, if once you verify valid username/password you plan on making a second call to get the user details, then clearly returning the object in the first place(and checking for null to verify existence) is a more efficient strategy in my opinion.