Repository navigation
Read directly from a ReadOnlySpan, no copy into a byte array - #11
Merged
Merged
Conversation
…rray The converter could only be handed a byte[]. A caller whose bytes arrive in anything else, a socket receive buffer, a rented buffer, a slice of a larger frame, had to copy them into a fresh array first, and that copy is larger than everything the converter itself allocates per message. ConvertFromByteArray now has ReadOnlySpan<byte> overloads in both shapes, new instance and reused instance. The span version is the real implementation, the array versions keep their null check and delegate to it, so both directions stay byte identical, which the golden vectors confirm. Reading a 38 byte frame out of a larger receive buffer: copy into an array first 132.05 ns 168 B span, no copy 75.13 ns 104 B span, reused instance 77.98 ns 48 B Roughly 50 ns of that gap is the FluentConditions guard clause that the array overload runs and the span overload does not, measured separately, so the copy itself accounts for the remaining part plus the 64 bytes. Removing that guard from the per message path is the next step and will lift both overloads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
ConvertFromByteArraygetsReadOnlySpan<byte>overloads in both shapes (new instance and reused instance). The span version is now the real implementation; thebyte[]overloads keep their null check and delegate to it.Why
The converter could only be handed a
byte[]. A caller whose bytes arrive in anything else, a socket receive buffer, a rented buffer, a slice of a larger frame, had to copy them into a fresh array first. That copy is bigger than everything the converter allocates per message, so it dominated what Phase 3 saved.Numbers
Reading a 38 byte frame that sits at a non zero offset inside a larger receive buffer:
Honest attribution: roughly 50 ns of that gap is the FluentConditions guard clause the array overload runs and the span overload does not, measured separately in the same run. The copy itself accounts for the rest plus the 64 bytes. Removing that guard from the per message path is the next PR and lifts both overloads.
Safety
TestSpanApi.cs.stackallocframe; reused instances; truncated and empty spans rejected asProtocolConverterException; null arrays still rejected;Prepare()still required.Breaking
IProtocolConverter<T>gains two members. That breaks hand written implementations and mocks, which is acceptable for the 4.0 major.🤖 Generated with Claude Code