Skip to content

perf: Encode FDv2 polling payloads in a single jwriter pass - #797

Draft
keelerm84 wants to merge 3 commits into
v9from
mk/SDK-2876/slow-polling-json
Draft

perf: Encode FDv2 polling payloads in a single jwriter pass#797
keelerm84 wants to merge 3 commits into
v9from
mk/SDK-2876/slow-polling-json

Conversation

@keelerm84

Copy link
Copy Markdown
Member
  • test: Add benchmarks for the FDv2 polling handlers
  • perf: Encode FDv2 polling payloads in a single jwriter pass

Whole-handler benchmarks for pollHandlerV2 (/sdk/poll) and
pollEvalHandlerV2Shared (/sdk/poll/eval) over a realistic data set (flags
with rules and targets, plus segments) at 100 and 2000 flags. These
establish the baseline for optimizing the payload serialization, which
live traces show dominating /sdk/poll request time.
The FDv2 polling handlers built their response by marshaling every item
into its own jwriter buffer, boxing each event into an any-typed struct,
and then running encoding/json over the whole document -- which walks it
by reflection and re-scans every embedded raw JSON object through its
compact() validator before copying it into yet another buffer.

Replace that with fdv2PayloadWriter, which writes the entire document in
one jwriter pass; put-object bodies are marshaled directly into the
output buffer. This is the same treatment the FDv2 SSE events received
in the streaming path, and the encoder is pinned to encoding/json's
output by equivalence tests (structurally equal; jwriter does not
HTML-escape, which the streaming encoders already ship).

Benchmarks (2000 flags): /sdk/poll 29.5ms -> 13.3ms per request (-55%)
with allocations down from 15046 to 45 (-99.7%); /sdk/poll/eval
1.97ms -> 1.54ms (-22%) with allocations halved, the remainder being
evaluation itself.

The pollingPayload/payloadEvent types move into test code, where they
still describe the wire format that responses are unmarshaled through.
The polling fdv2PayloadWriter and internal/streams' SSE encoders spell
out the same protocol event shapes in separate jwriter code. These tests
run the same inputs through both and require identical event names and
data JSON, so a protocol-shape change in either implementation fails
until both move. The streaming encoders' output shapes were otherwise
almost unasserted.

The comparison also covers the intent payloads: the streams package
derives the up-to-date and full-transfer intents from the selector
internally, so the payloads the polling handlers construct must match.
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.

1 participant