Skip to content

perf: optimize JSON struct deserialization - #213

Open
JairusSW wants to merge 3 commits into
mainfrom
agent/optimize-json-struct-deserialization
Open

perf: optimize JSON struct deserialization#213
JairusSW wants to merge 3 commits into
mainfrom
agent/optimize-json-struct-deserialization

Conversation

@JairusSW

@JairusSW JairusSW commented Jul 24, 2026

Copy link
Copy Markdown
Owner

What changed

  • admit SIMD exact-source field traces only after the same immutable source/output pair repeats
  • avoid recording and clearing trace state for request-style workloads with changing payloads
  • scan long string values 16 UTF-16 code units at a time by narrowing two vectors into one byte vector; unsigned saturation keeps non-ASCII input delimiter-safe without a separate ASCII pass
  • extend the existing validated two-coordinate SIMD path to fresh as well as reused float arrays, with complete fallback for other shapes
  • construct fresh two-number coordinate arrays with an exact two-element backing buffer instead of AssemblyScript's default eight-element minimum
  • add changing-payload fresh and reuse benchmarks for small, medium, large, Canada, GitHub Events, and Twitter corpora
  • document the JSON Struct and Generated Codec vocabulary in CONTEXT.md

Why

The existing reuse trace path recorded every string and object field even when consecutive requests used different source strings. Those traces could never produce a cache hit.

For fresh materialization, long UTF-16 string scans handled only eight code units per vector, and fresh GeoJSON coordinate pairs missed the existing two-slot fast path. Each pair also reserved six unused numeric slots; Canada contains 55,563 coordinate pairs, making that allocator overhead the largest remaining hot-path cost.

Impact

Reuse latency improvements from the trace-admission change remain approximately:

  • small: 14–17%
  • medium: 53%
  • large: 53%
  • GitHub Events: 30.5%
  • Twitter: 34.6%
  • Canada: effectively flat

Against json-parser-benchmarks, the fresh-materialization changes now measure approximately:

  • GitHub Events: 569 MB/s, about +5%
  • Twitter: 646 MB/s, about +1%
  • Canada: 360–362 MB/s, about +25%
  • geometric mean: about 510 MB/s, roughly +9%

The comparison remains below json-ty's 816 MB/s geometric mean. The remaining gap is dominated by representation/allocation differences: json-as constructs managed AssemblyScript strings and nested arrays, while json-ty parses raw UTF-8 into a compact releasable document representation.

The exact-capacity coordinate buffers also materially reduce heap pressure. On the memory-instrumented fresh Canada minified benchmark, peak Wasm memory fell from 316 MiB to 158 MiB and in-flight live memory fell from about 74.7 MiB to 11.2 MiB. Post-GC retention remains stable.

Validation

  • 33,969 public API assertions across NAIVE, SWAR, and SIMD
  • 40,797 RFC/strict assertions across all modes
  • transform tests
  • type checking
  • lint and repository pre-commit verification
  • V8 primary benchmarks and WAVM secondary checks
  • heap-analyzer differentials
  • SWAR binary identity and SIMD code-size checks

@JairusSW
JairusSW marked this pull request as ready for review July 24, 2026 04:29
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