-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Eliminate allocation in StreamAsIStream.Read
#6632
Conversation
The native/managed interop layer will allocate a byte array to marshal a native buffer to the StreamDescriptor.Read delegate. By using Span<byte> and the corresponding overload of Stream.Read, we can read directly into the caller's buffer when CManagedStream::Read calls this delegate.
Although only 4 milliseconds have been reduced, it is important to reduce 79KB of memory allocated. |
Actually only 4 microseconds faster, which is well within the margin of error. I'm not claiming that this PR is any faster; the primary goal is to eliminate managed allocations (which were previously equal in size to the input size of the image) and GCs. |
No regression when the array is bigger than int? Doesn't AsSpan throw with negative numbers? |
There's no regression because the old code cast the length to an |
@dipeshmsft Could this PR be considered for the 8.x release series? It feels like a small change that has measurable allocation/GC benefits. |
@bgrainger - Unfortunately, .NET8 RC candidates are locked in and we won't be able to take this in for .NET8. However, we'll consider this PR for upcoming CTP runs and have it merged asap. |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Thanks @bgrainger for the contribution! |
Description
The native/managed interop layer will allocate a byte array to marshal a native buffer to the
StreamDescriptor.Read
delegate. By usingSpan<byte>
and the corresponding overload ofStream.Read
, we can read directly into the caller's buffer whenCManagedStream::Read
calls this delegate.Sample improvement by running a benchmark to create a
BitmapImage
with aMemoryStream
StreamSource
containing a 79KB PNG:Customer Impact
Unnecessary allocation and memory copy between native/managed buffers.
Regression
No
Testing
Tested in real-world application via incorporation into Faithlife.Wpf.
Risk
Minimal.
Microsoft Reviewers: Open in CodeFlow