Avoid trimming groupings in GroupBy with result selectors #15367
Conversation
At https://github.com/dotnet/corefx/issues/8848#issuecomment-274222936
That's a reason for keeping it as-is. It's been possible to do this since 3.5, so there could be dependencies on this.
That's a big reason for wishing it was done like this (or at the very least, that something hid the array from It's a good change, with a result that is both better in what it exposes and I would imagine faster in most cases (though perhaps slower on repeated iterations, or inputs that just happen to hit a size threshold perfectly). The question is whether that break is too strong a break. |
If we exposed the More reasonably, any operations (such as those in |
@JonHanna Grouping implements
Maybe, but someone who is familiar with functions like |
Ah. True that it does implement that. Hurrah.
If they did it, they'd likely done it as an optimisation. Not a safe optimisation, granted. |
Self-note: https://github.com/dotnet/corefx/pull/15365/files#diff-87d47ae56131fbbcc56111336ea8e9e3R247 touches on this when using |
@@ -247,8 +245,7 @@ public IEnumerable<TResult> ApplyResultSelector<TResult>(Func<TKey, IEnumerable< | |||
do | |||
{ | |||
g = g._next; | |||
g.Trim(); | |||
yield return resultSelector(g._key, g._elements); | |||
yield return resultSelector(g._key, g); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep Trim here. There could be reasons why it was done. Most likely performance of iterating.
Also, while it is unfortunate to expose the array, there is a risk now that someone took dependency on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another reason might be to separate keys from elements before passing to the selector - that is just to ensure if eventually only elements are retained, they do not hold the keys as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This applies to other cases where Trim is used.
I think we should keep trimming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, while it is unfortunate to expose the array, there is a risk now that someone took dependency on that.
Is there really? I mean Linq is generally not that high-perf anyways so it's hard for me to imagine someone (purposefully or accidentally) casting the parameter to an array to get better perf.
Another reason might be to separate keys from elements before passing to the selector - that is just to ensure if eventually only elements are retained, they do not hold the keys as well.
Good point. I think we can fix this and still avoid trimming by passing in a new ArraySegment<T>(g._elements, 0, g._count)
, though.
@VSadov, do you want to continue exploring this or should it be closed? |
I am not sure this is worth pursuing. The problem to solve here is not that big. It seems it is better to just leave this as it is |
AFAICS we can pass the grouping as the enumerable rather than the array, which eliminates the need for an expensive resize. It also prevents users from getting at the underlying array of the grouping by casting the enumerable to a
TElement[]
.Related: https://github.com/dotnet/corefx/issues/8848