Skip to content
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

Span<T> in C# on RepeatedField<T> #16745

Open
PascalSenn opened this issue May 5, 2024 · 4 comments
Open

Span<T> in C# on RepeatedField<T> #16745

PascalSenn opened this issue May 5, 2024 · 4 comments
Assignees
Labels

Comments

@PascalSenn
Copy link

PascalSenn commented May 5, 2024

What language does this apply to?
c# protobuf 3

Describe the problem you are trying to solve.

The issue #6217 was recently marked as stale, but the problem it addresses is still relevant. The goal is to work with a Span<T> of a RepeatedField<T> in C# Protobuf, which would allow for working with apis like vectors and reuse of already allocated memory. Accessing the internal array of a RepeatedField would make this possible.

I have read through the discussions on the issue and the PR #6538.

Describe the solution you'd like
Ideally, provide access to a ReadOnlySpan<T> of the internal array of a RepeatedField<T>. I understand that modifying the array after creating a span from it could lead to unexpected behavior, but in most cases, incoming messages are not mutated.

Describe alternatives you've considered
If providing access to the internal data structures through ReadOnlySpan is not feasible, an alternative solution would be to introduce CopyTo methods that accept a Span<T> as the destination. The proposed method signatures are:

    public void CopyTo(Span<T> destination) {..}
    public void CopyTo(Span<T> destination, int length) {..}
    public void CopyTo(Span<T> destination, int sourceIndex, int destinationIndex, int length) {..}

Additional context
Add any other context or screenshots about the feature request here.

@PascalSenn PascalSenn added the untriaged auto added to all issues by default when created. label May 5, 2024
@shaod2 shaod2 added c# and removed untriaged auto added to all issues by default when created. labels May 7, 2024
@jskeet
Copy link
Contributor

jskeet commented May 7, 2024

I'd want the input of @JamesNK on this (for consistency with other .NET APIs), but I don't think I object to exposing a ReadOnlySpan<T>. Can you create a PR for us to review?

@PascalSenn
Copy link
Author

@jskeet The objection on ReadOnlySpan<T> in the initial proposal was about the possibility of resizing the underlying array.

#6538 (comment)

Also note that exposing the data as read-only (ReadOnlySpan) addresses some concerns over the safety, but there are still some potential issues - e.g. the returned span is bound to the current array, but if a repeated field gets resized, a new internal array is allocated, so the span will point to a dead array and all the changes will be lost.

If exposing ReadOnlySpan<T> is an option. Something simple as this could work:
#16772

If you prefer a CopyTo approach, let me know.

@jskeet
Copy link
Contributor

jskeet commented May 8, 2024

@PascalSenn: Yes, basically this ends up being problematic any time things are changed. The use of a span makes it less likely that that will cause problems, as it's harder to keep one around long term. (The code using the span would need to call the code that modifies the repeated field.) That's not true with ReadOnlyMemory<T> though... for the use cases you're thinking of, would just having ReadOnlySpan and not ReadOnlyMemory be sufficient? (We could have a CopyTo method accepting a Memory<T> if that would be useful.)

Personally I'm okay with documentation on the span property that says "if the repeated field is modified, you're in undefined territory in terms of the span".

@PascalSenn
Copy link
Author

PascalSenn commented May 8, 2024

@jskeet
I removed the exposed ReadOnlyMemory<T> in the PR and added the note into the XML Doc string of ReadOnlySpan<T>.

I do not require ReadOnlyMemory<T> for my use case as I can also just pass the RepeatedField<T> around and use .Span on it for direct access. (also .Span.CopyTo if needed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants