-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Poor codegen for collection expression spread (IEnumerable<T> -> ImmutableArray<T>) #71296
Comments
The spec allows this. |
Had a feeling that was the case but wanted to double check, that's great 🙂 |
After the spread optimization PR, codegen is as follows: SharpLab List<string> list = new List<string>();
list.AddRange(items);
return ImmutableCollectionsMarshal.AsImmutableArray(list.ToArray()); This is better than the original but not great. Let's use this issue to track completing the relevant bullet from #68785:
I'd prefer that our solution has the following traits:
|
@RikkiGibson I have a question related to this and also #71292. Right now all of these optimizations are hardcoded in the compiler, which means they (1) need someone in the compiler team to specifically implement them, and also (2) they won't work with user defined collection types that are not recognized by Roslyn. Here's an idea, would it be possible to make it so that if:
Roslyn will simply lower it to For instance, with this optimization, that Thoughts? 🙂 |
We expect user defined types to make use of collection-expr optimizations, to the extent that they are created in terms of well-known types. For example Generally when a type has CollectionBuilder, that strategy is considered better than the others (IIRC). ImmutableArray is just special, and we happen to think our "create an array then cast to ImmutableArray" approach is better--and it is, when it comes to creating from scalars, since it removes the value copy from the span to the final array. However for |
I would suggest to break things down and focus here only on single-spread case for immutable arrays. For instance, we need to determine, when we should pick However, what should we do if we the underlying spreading expression type can be an immutable array, e.g. in cases, when it is an interface, that
@RikkiGibson What do you think? |
It is fine to use ToImmutableArray when a single spread of reference type is implicitly convertible to I would not invest time in honing it further than that for now. There is a broader optimization space that I would want to invest in first. I also think skipping the copy for |
Agreed. This is a better place for our analyzers to call out an unnecessary copy. Something I believe they already do on unnecessary explicit ToImmArray calls |
Related to #71195
Version Used: 4.9.0-ci (a8119d1)
Steps to Reproduce:
sharplab
Expected Behavior:
OR
Actual Behavior:
@RikkiGibson @CyrusNajmabadi not entirely sure whether the spec allows this, I think the problem is that the factory API is
CreateRange
, but[CollectionBuilder]
overImmutableArray<T>
usesCreate
as the method name. Perhaps it would be possible to just hardcode these additionalImmutableArray<T>
cases? Though it'd be nice to have a more general solution 🤔The text was updated successfully, but these errors were encountered: