-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[API Proposal]: Expose a way to get either directly to the backing array of an ImmutableArray.Builder, or get it as a span. #111813
Comments
Tagging @ToddGrun @stephentoub |
Tagging subscribers to this area: @dotnet/area-system-collections |
Is there a benefit to getting the array and slicing over a hypothetical |
Yes. Being able to use in scenarios where a span isn't viable. like in async code. My example just showed that if we were using a span (as opposed to some other abstraction over a contiguous sequence of elements) it would work with this new api. |
Would returning This method looks closer to |
If it can return something without allocation that allows uniform processing with the array that an IA returns and is not a ref struct, it's likely ok. |
Looking at the defs of these, i think ArraySegment most aligns with how i think of things. it's definitely an array, and just represents a chunk within it. So if you wanted to expose thi as ArraySegment, that seems fine to me :) |
Just to clarify, you only need to access the segment corresponding to the current |
Correct.
Right. hence why, morally, i'm just fine with this exposing the array and just leaving it to the caller to do the right thing. But i'm ok with any route :) |
namespace System.Runtime.InteropServices;
public static class ImmutableCollectionsMarshal
{
public static Memory<T> AsMemory<T>(ImmutableArray<T>.Builder builder);
} |
Background and motivation
Roslyn has several internal algorithms (including as very hot spots in our core analyzer driver) where we may have data flowing in as either an
ImmutableArray<T>
(when the data is fixed and known ahead of time), or as anImmutableArray<T>.Builder
(when it's more the result of some scratch computation that we still want to operate on).Our choices when we run into this have not been attractive. We either need to make duplicate copies of the code (increasing redundancy and possibility of increases bugs), or we need to update the core functions to take an
IEnumerable<T>
(or some other list-like interface). This is not great as this both boxes theImmutableArray<T>
case, and then has costs later on when we iterate the values.Ideally, we could write the core logic to operate uniformly. Either on an array+length (or just a span). With ImmutableArray it is possible to get it as a span with .AsSpan, or get to the backing array with ImmutableCollectionsMarshal. However, no such facility exists for
IA.Builder
. This blocks us from having uniform processing logic that operates on a contiguous sequence of values, which might be coming from either source.Our request is to provide some mechanism to expose thsi data from an IA.B. There are a few concerns here:
If the array (or span) is exposed, then it might no longer be valid if the IA.B is mutated. As such, this probably makes to sense to add as an API on ImmutableCollectionsMarshap, not on IA.B itself.
This would lock IA.B into being definitely backed by an array. That said, my belief is that that is already a requirement of the IA.B api because it already has a
MoveToImmutable
method which is guaranteed to work as long as the current capacity matches the count of the builder:This could not be changed (say, to have multiple internal arrays) as then MoveToImmutable would no longer be an O(1) move as promised, and which lots of consumption code depends on.
API Proposal
API Usage
Alternative Designs
No response
Risks
This forces the internal backing storage of a builder to always be a contiguous array. However, as stated in the proposal above, it seems like this is already a requirement that cannot be violated to begin with. So having one more dependency on this is likely fine.
The text was updated successfully, but these errors were encountered: