Merged
Conversation
Add BenchmarkReadAt exercising the full ReadAt() code path for both plain and encrypted sessions.
Introduce a sync.Pool of byte buffers in conn to reuse receive buffers across reads. The pooled buffer is threaded through tryHandle into requestResponse so callers can return it after processing. Compound and encrypted responses that produce new buffers release the pool buffer immediately.
This change threads through the return of pooled buffers to the pool at the end of a readAt call. This required adding a new return value to readAtChunk and threading through the response struct to allow lifecycle management of the pooled read buffers Before: ``` BenchmarkReadAt/Plain/1KB-10 309301 3871 ns/op 264.55 MB/s 1628 B/op 6 allocs/op BenchmarkReadAt/Plain/64KB-10 110104 10778 ns/op 6080.70 MB/s 74221 B/op 6 allocs/op BenchmarkReadAt/Plain/1MB-10 17011 69926 ns/op 14995.60 MB/s 1057380 B/op 6 allocs/op BenchmarkReadAt/Encrypted/1KB-10 230868 5120 ns/op 200.00 MB/s 3554 B/op 7 allocs/op BenchmarkReadAt/Encrypted/64KB-10 37930 31865 ns/op 2056.71 MB/s 164388 B/op 7 allocs/op BenchmarkReadAt/Encrypted/1MB-10 3502 338054 ns/op 3101.80 MB/s 2377206 B/op 8 allocs/op BenchmarkRoundTrip/Plain/1KB-10 324889 3697 ns/op 277.00 MB/s 1627 B/op 6 allocs/op BenchmarkRoundTrip/Plain/64KB-10 126373 9288 ns/op 7056.29 MB/s 74212 B/op 6 allocs/op BenchmarkRoundTrip/Plain/1MB-10 21868 54787 ns/op 19139.10 MB/s 1057354 B/op 6 allocs/op BenchmarkRoundTrip/Encrypted/1KB-10 237756 5032 ns/op 203.51 MB/s 3554 B/op 7 allocs/op BenchmarkRoundTrip/Encrypted/64KB-10 39066 30867 ns/op 2123.14 MB/s 164384 B/op 7 allocs/op BenchmarkRoundTrip/Encrypted/1MB-10 3765 311547 ns/op 3365.70 MB/s 2377363 B/op 7 allocs/op ``` After: ``` BenchmarkReadAt/Plain/1KB-10 339576 3543 ns/op 289.05 MB/s 492 B/op 5 allocs/op BenchmarkReadAt/Plain/64KB-10 175285 6744 ns/op 9718.10 MB/s 520 B/op 5 allocs/op BenchmarkReadAt/Plain/1MB-10 27549 42779 ns/op 24511.65 MB/s 757 B/op 5 allocs/op BenchmarkReadAt/Encrypted/1KB-10 234076 4977 ns/op 205.76 MB/s 2294 B/op 6 allocs/op BenchmarkReadAt/Encrypted/64KB-10 42075 28553 ns/op 2295.28 MB/s 92763 B/op 6 allocs/op BenchmarkReadAt/Encrypted/1MB-10 3901 300217 ns/op 3492.73 MB/s 1348399 B/op 7 allocs/op BenchmarkRoundTrip/Plain/1KB-10 329589 3500 ns/op 292.53 MB/s 492 B/op 5 allocs/op BenchmarkRoundTrip/Plain/64KB-10 253318 4782 ns/op 13705.62 MB/s 540 B/op 5 allocs/op BenchmarkRoundTrip/Plain/1MB-10 54456 22056 ns/op 47541.85 MB/s 798 B/op 5 allocs/op BenchmarkRoundTrip/Encrypted/1KB-10 241818 4810 ns/op 212.90 MB/s 2294 B/op 6 allocs/op BenchmarkRoundTrip/Encrypted/64KB-10 43735 27694 ns/op 2366.45 MB/s 93314 B/op 6 allocs/op BenchmarkRoundTrip/Encrypted/1MB-10 4075 288285 ns/op 3637.29 MB/s 1337363 B/op 7 allocs/op ```
The decrypt scratch buffer (append of EncryptedData + Signature) was allocated on every encrypted packet. Get a *recvBuf from conn.recvPool instead, and thread it back through runReceiver->tryHandle-> requestResponse so the caller's freeRecvBuf returns it to the pool. Shaves an allocation from the encrypted path Before: [see last commit] After: ``` BenchmarkReadAt/Encrypted/1KB-10 245488 4767 ns/op 214.83 MB/s 370 B/op 4 allocs/op BenchmarkReadAt/Encrypted/64KB-10 46538 25846 ns/op 2535.60 MB/s 437 B/op 4 allocs/op BenchmarkReadAt/Encrypted/1MB-10 4057 289344 ns/op 3623.97 MB/s 1663 B/op 4 allocs/op BenchmarkRoundTrip/Encrypted/1KB-10 294138 4079 ns/op 251.05 MB/s 369 B/op 4 allocs/op BenchmarkRoundTrip/Encrypted/64KB-10 53742 23999 ns/op 2730.73 MB/s 466 B/op 4 allocs/op BenchmarkRoundTrip/Encrypted/1MB-10 4387 270263 ns/op 3879.83 MB/s 2047 B/op 4 allocs/op ```
arashpayan
reviewed
Mar 13, 2026
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.
Introduce a sync.Pool of byte buffers in conn to reuse receive
buffers across reads. The pooled buffer is threaded through tryHandle
into requestResponse so callers can return it after processing.
Compound responses that produce new buffers "leak" the pooled
buf so that it is captured by GC.
Indeed, only the readAt call is fully plumbed through with this set
of changes. If we want to consider further changes we may either
want to set up a pattern (effectively a rewrite of sendRcv) or break
up individual uses of sendRcv as they show up in performance
benchmarking.