Skip to content

Store a sent packet's first stream send inline - #201

Open
rnro wants to merge 1 commit into
apple:mainfrom
rnro:alloc/sent-streams-inline
Open

rnro wants to merge 1 commit into
apple:mainfrom
rnro:alloc/sent-streams-inline

Conversation

@rnro

@rnro rnro commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Every packet that carries stream data records which stream sends it carried in
TransmittedItems.sentStreams, and keeps the record until the packet is
acknowledged or declared lost. The record was an array, so each such packet
allocated storage for it, though a packet almost always carries one stream.
SentStreams keeps the first send inline and only allocates for the rest.
SentStream holds nothing but values, so it is now copyable, which lets the
inline slot be an ordinary optional.

Measured on my Mac against main with the package's QUIC benchmark tools.
Allocation counts come from full malloc stack logging, which records every
allocation:

QUICTransfer -size 1200, per message      24.37 -> 23.31
QUICTransfer, per 500 KB transfer       6,187.6 -> 5,747.9
QUICHandshake, per connection           1,947.4 -> 1,944.8
QUICStreamLoad, per stream                111.8 -> 109.8

The stream load still allocates for a second send in about one packet in
seventeen.

Wall-clock time comes from running main, this change and the other changes
measured alongside it in a rotating order for 9 rounds, and comparing each run
with main's in the same round. Changes moved paths they do not touch by up to
about 1.3%, so differences that size count as noise. Nothing changed beyond
noise.

Every packet that carries stream data records which stream sends it carried in
`TransmittedItems.sentStreams`, and keeps the record until the packet is
acknowledged or declared lost. The record was an array, so each such packet
allocated storage for it, though a packet almost always carries one stream.
`SentStreams` keeps the first send inline and only allocates for the rest.
`SentStream` holds nothing but values, so it is now copyable, which lets the
inline slot be an ordinary optional.

Measured on my Mac against `main` with the package's QUIC benchmark tools.
Allocation counts come from full malloc stack logging, which records every
allocation:

  QUICTransfer -size 1200, per message      24.37 -> 23.31
  QUICTransfer, per 500 KB transfer       6,187.6 -> 5,747.9
  QUICHandshake, per connection           1,947.4 -> 1,944.8
  QUICStreamLoad, per stream                111.8 -> 109.8

The stream load still allocates for a second send in about one packet in
seventeen.

Wall-clock time comes from running `main`, this change and the other changes
measured alongside it in a rotating order for 9 rounds, and comparing each run
with `main`'s in the same round. Changes moved paths they do not touch by up to
about 1.3%, so differences that size count as noise. Nothing changed beyond
noise.
var sentStreams = NetworkUniqueArray<SentStream>()

/// The stream sends a packet carried.
///

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants