-
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
Fix BufferExtensions.Write to specify sizeHint to GetSpan #110047
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The "slow path" below is never going to be hit now, and the LOH will start getting hit
#110028 (comment)
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.
Why not? The size is a hint. The IBufferWriter implementation is neither required nor guaranteed to return that as a minimum.
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.
Unless my coffee hasn't kicked in and I'm misreading the doc comments, the span returned must be at least
sizeHint
in size.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.
Grr. Apparently we retcon'd it (but obviously left the parameter name):
dotnet/corefx#35554
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.
Why are we not concerned about this with every other use of GetSpan/GetMemory? Literally every other use I've found in product src is passing in a value.
(Also, the majority of IBufferWriter implementations pool.)
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.
Laziness or not perf sensitive code? It's definitely easier in most cases to just grab a large buffer and write instead of writing a loop.
But there are lots of cases where we are careful about what we pass in:
https://github.com/dotnet/aspnetcore/blob/8d0f798cc4de54a2851748be635a58eadbf79593/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketConnection.cs#L152
https://github.com/dotnet/aspnetcore/blob/8d0f798cc4de54a2851748be635a58eadbf79593/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs#L1865
https://github.com/dotnet/aspnetcore/blob/8d0f798cc4de54a2851748be635a58eadbf79593/src/Middleware/OutputCaching/src/FormatterBinaryWriter.cs#L110
https://github.com/dotnet/aspnetcore/blob/8d0f798cc4de54a2851748be635a58eadbf79593/src/Caching/SqlServer/src/DatabaseOperations.cs#L324
True, but I think we generally would like to avoid pooling large arrays?
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.
Ah, the joys of abstractions.
It seems like what this really wants to say is "I have
value.Length
bytes of material; but I don't care how many iterations it takes us to copy". So sort ofwriter.EnsureAvailableCapacity(value.Length)
, thenwriter.GetNextWritableChunk()
(in case it did it with pages instead of linear allocation).But we've decided that for IBufferWriter you say the minimum size you need so you can then just splat data in without doing any local bounds checking (
dest[0] = 0x04; params.Q.X.CopyTo(dest.Slice(1)); params.Q.Y.CopyTo(dest.Slice(1 + params.Q.X.Length));
); making it suitable for bit-banging at the expense of bulk copying.So we could say here
writer.GetSpan(int.Min(value.Length, 4096))
to avoid forcing a paging implementation to make one large page, but that 4096 is this function still having opinions as to a page size.If it was an class instead of an interface I'd wonder if we wanted to just add an EnsureCapacity-type method; but since it's an interface that's hard.
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.
We can add EnsureCapacity but wouldn't it be the same? Would it return anything?
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.
Would a
Write(ReadOnlySpan<T>)
DIM onIBufferWriter<T>
work?