- bufferRing: add consumeFront() method to eliminate duplicate buffer
consumption code in tryReadV1/tryReadV2, move allocator.Put() outside
critical section to reduce lock hold time
- Session.IsClosed(): replace select-based check with atomic flag for
faster hot path execution, add 'closed' field with atomic operations
- shaperQueue: convert count to atomic int64, Len() and IsEmpty() now
lock-free using atomic.LoadInt64()
- recvLoop: move stream.fin() and stream.update() calls outside lock
scope in cmdFIN/cmdUPD handlers to reduce lock contention
- stream: extract checkWriteClosed() helper to deduplicate close checks
in writeV1/writeV2
All tests pass with race detector enabled.
- Add writeRequestPool to reuse writeRequest objects and their result
channels in session.go, reducing allocations per write operation
- Add shaperHeapPool to reuse shaperHeap objects in shaper.go, avoiding
heap allocations when streams are created/destroyed
- Pre-allocate buffers and heads slices with capacity 8 in newStream()
to reduce slice growth allocations during data transfer
Benchmark results (128KB data transfer):
Before: 36 allocs/op, ~910 MB/s
After: 20 allocs/op, ~950 MB/s
This reduces memory allocations by 44% and improves throughput by ~5%.