perf: Lexicon response deserialization allocations #202

Closed
opened 2026-10-05 02:29:53 +00:00 by Grandiras · 1 comment
Owner

Goal

Cut allocations and CPU when deserializing Lexicon responses: a 30-item getAuthorFeed page allocates ~55 KB through the in-process XRPC path. Look at the model layer (LexObject extension data, open unions, AtProtoJsonDefaults converters, record deserialization) without changing behaviour or public API.

Scope

src/ATProtoNet/Serialization, src/ATProtoNet/Models, and the model files (*Models.cs) under src/ATProtoNet/Lexicon.

### Goal Cut allocations and CPU when deserializing Lexicon responses: a 30-item `getAuthorFeed` page allocates ~55 KB through the in-process XRPC path. Look at the model layer (`LexObject` extension data, open unions, `AtProtoJsonDefaults` converters, record deserialization) without changing behaviour or public API. ### Scope `src/ATProtoNet/Serialization`, `src/ATProtoNet/Models`, and the model files (`*Models.cs`) under `src/ATProtoNet/Lexicon`.
Author
Owner

Investigated, no change. Measured with real AppView JSON: a 30-item getAuthorFeed page (237 KB JSON) allocates ~521 KB. A raw JsonElement parse of the same bytes allocates 423 KB, so the typed path is near the floor.

About 62% of the allocation is the raw JSON held by public JsonElement properties: FeedReplyRef.Root/Parent, PostView.Record and EmbeddedRecord.Value. Extension data, union cloning, converter resolution and the union double scan (fixed in #191) are all already cheap.

A real reduction needs a public API decision, such as typing FeedReplyRef.Root/Parent as the already-modelled post union instead of JsonElement. That is a breaking change for 0.8, left to the owner.

Investigated, no change. Measured with real AppView JSON: a 30-item getAuthorFeed page (237 KB JSON) allocates ~521 KB. A raw `JsonElement` parse of the same bytes allocates 423 KB, so the typed path is near the floor. About 62% of the allocation is the raw JSON held by public `JsonElement` properties: `FeedReplyRef.Root`/`Parent`, `PostView.Record` and `EmbeddedRecord.Value`. Extension data, union cloning, converter resolution and the union double scan (fixed in #191) are all already cheap. A real reduction needs a public API decision, such as typing `FeedReplyRef.Root`/`Parent` as the already-modelled post union instead of `JsonElement`. That is a breaking change for 0.8, left to the owner.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/ATProto.NET#202
No description provided.