Fix for methods returning null collections#18
Conversation
|
Hi Jakub/All We should be careful on the null collections change as we should prioritize performance against clarity. “The faster code is the one that do not execute” as you probably know ☺ I know .net will manage quite fast to create an empty object that will be collected later by GC and looking to this as a single operation is not that much. At millions of requests scale, this matters a lot. Return a null and checking for null is faster. There are other considerations, like if we are overriding built-in methods that .net already Maybe to create companion methods TryXXXX that returns bool value if the TryXXXX has been success and the data is ok (like int.TryParse) I’m asking to put piece of the PR on hold until we reach a consensus on how to handle all this. Regards From: Jakub Konecki [mailto:notifications@github.com] I believe returning an empty collection should be preferred over returning a null - this helps avoiding NullRerefenceExceptions and allows a straightforward client loops. I've turned a simple comment to method documentation tag in ClientDirectory class (where returning null seems to be the required behaviour) in order for it to pop up in intellisense. You can view, comment on, or merge this pull request online at: Commit Summary
File Changes
Patch Links: — |
|
I fully agree with you, Jesus. My preference is for the code to be safe but I wouldn't mind if the PR is rejected if there are genuine arguments for returning nulls. |
|
The general reason to return nulls instead of empty collections/dictionaries indeed has been performance concerns - to avoid unnecessary allocations and GC pressure. However, in these particular cases I don't think we should have perf concerns as the ConsistentRing and Directory methods are only invoked upon a cluster change, so we could make them safe, I think. Some of the SetExtensions methods are use by the test code that we haven't ported to Github yet. So I don't think there is a perf concern their at the moment either. I'll wait for Gabi to weigh in. |
|
Hi , As long it is not in the critical path and probably being better for the cluster management classes to be the safer as possible, sounds like a good thing. Jakub, I understand is safer to not return null, and I’m happy with this. Just knowing the implications to create/GC objects in a critical path (related to performance) I didn’t check what classes were impacted, anyways, I don’t have yet the full Orleans architecture in my mind and can tell really what areas were impacted. Let’s wait for Gabriel. Jesus From: Sergey Bykov [mailto:notifications@github.com] The general reason to return nulls instead of empty collections/dictionaries indeed has been performance concerns - to avoid unnecessary allocations and GC pressure. However, in these particular cases I don't think we should have perf concerns as the ConsistentRing and Directory methods are only invoked upon a cluster change, so we could make them safe, I think. Some of the SetExtensions methods are use by the test code that we haven't ported to Github yet. So I don't think there is a perf concern their at the moment either. I'll wait for Gabi to weigh in. — |
|
In general, I totally agree with Jesus on the importance of performance. And Jakub's point about cleaner APIs is also valid.
Specifically, in those cases:
I will think more about it and pull this request (with appropriate modifications) tomorrow. |
|
Wouldn’t use a static readonly instance cause problems when use in fluent way or when trying to manipulate the collection? I mean, I like this approach and I used it on some architectures like when I wanted to have a default initialized class and use it as However in a case where I do a ToList() and then the code, by some criteria (i.e. count == 0 ) choose to manipulates the collection (i.e. adding elements) I’ll receive an exception In the other hand if we do not use readonly there is a chance code will mutate the ‘what has become a singleton dummy instance’ to a new state causing I believe that if we want to follow this approach will require a bit more of research, probably the best as Gabriel suggest would be to mimic the All this talking from the broad architecture point of view and not about the specifics in the affected classes that maybe the idea fits if data is immutable, I’m still learning Orleans.. Also, I concur public APIs are the most important. As they are exposed to developers they must be as perfect as possible, the internal layers should be as practical as possible and we should stock to some established common pattern. Jesus From: Gabriel Kliot [mailto:notifications@github.com] In general, I totally agree with Jesus on the importance of performance. And Jakub's point about cleaner APIs is also valid.
Specifically, in those cases:
I will think more about it and pull this request (with appropriate modifications) tomorrow. — |
|
Of course, I meant only to use preallocated static readonly only for cases that do not manipulate the collection. I all the examples in this pull request, and in most places in the runtime, we do not manipulate the returned collection. We hardly ever manipulate the returned collection. If we need to do that, we refactor the common logic between caller and callee into some shared component. This is part of the discipline of making sharing between components explicit, which is a good practice for multi threaded code. |
|
Another option could be changing the return type from |
|
Yes, agree. |
|
OK. Let me see what kind of impact that would make and I'll update PR. |
|
Jakub, for this specific set of changes I would not do much. As I wrote, all except Set extensions are internal methods. So we can even leave them as is. Set extensions are the only problem, but since we don't use them anyway, we can just remove those methods. |
|
All right. I'll just get rid of Set extension methods and leave the rest as On Mon, 26 Jan 2015 18:37 Gabriel Kliot notifications@github.com wrote:
|
|
I reverted the changes and left the Set extension methods intact as they are actually used. |
|
Ok, Jakub. I will work on merging that pull request. Thanks. |
…ollections Fix for methods returning null collections
I believe returning an empty collection should be preferred over returning a
null- this helps avoidingNullRerefenceExceptionsand allows a straightforward client loops.I've turned a simple comment to method documentation
<summary>tag inClientDirectoryclass (where returningnullseems to be the required behaviour) in order for it to pop up in intellisense.