Skip to content

feat(smithy-json): add configurable eager deserialization - #850

Open
stobrien89 wants to merge 2 commits into
developfrom
json-eager-deserialization
Open

stobrien89 wants to merge 2 commits into
developfrom
json-eager-deserialization

Conversation

@stobrien89

Copy link
Copy Markdown
Contributor

Description

Adds configurable eager JSON deserialization for buffered payloads while preserving incremental parsing for streaming readers.

Changes

  • Adds JSONDeserializationMode with AUTO, EAGER, and STREAMING modes.
  • Defaults to AUTO, which eagerly parses bytes and incrementally parses BytesReader inputs.
  • Adds an eager deserializer backed by Python's native JSON parser.
  • Exposes json_deserialization_mode through generated Rest JSON and AWS JSON client configurations.
  • Allows users to explicitly restore the existing streaming behavior.
  • Preserves handling for Smithy documents, blobs, timestamps, non-finite floats, nulls, and unknown members.
  • Adds runtime, code generation, compatibility, and protocol tests.
  • Documents the performance and memory tradeoff between eager and streaming modes.

Performance

Benchmarks used Python 3.12.14 on x86_64 with 5,000 warmup iterations and 10,000 measured iterations per case.

Every measured JSON deserialization case improved.

Summary

The combined values below are the sums of the p50 values for each protocol's cases.

Protocol Cases Before p50 After p50 Improvement
Rest JSON 1 5 88.273 µs 70.296 µs 20.4%
AWS JSON 1.0 8 1,965.878 µs 912.633 µs 53.6%
AWS JSON 1.1 8 1,965.691 µs 920.010 µs 53.2%
Overall 21 4,019.842 µs 1,902.939 µs 52.7%

Rest JSON 1

Case Before p50 After p50 Improvement
restJson1_CopyObjectOutput_Baseline 3.233 µs 3.160 µs 2.3%
restJson1_CopyObjectOutput_M 41.624 µs 24.440 µs 41.3%
restJson1_GetObject_S 14.364 µs 14.185 µs 1.2%
restJson1_GetObject_M 14.523 µs 14.237 µs 2.0%
restJson1_GetObject_L 14.529 µs 14.274 µs 1.8%

AWS JSON 1.0

Case Before p50 After p50 Improvement
awsJson1_0_GetItemOutput_Baseline 10.946 µs 7.877 µs 28.0%
awsJson1_0_GetItemOutput_S 44.745 µs 21.305 µs 52.4%
awsJson1_0_GetItemOutput_M 132.478 µs 59.910 µs 54.8%
awsJson1_0_GetItemOutput_L 762.325 µs 342.355 µs 55.1%
awsJson1_0_GetItemOutputBinary_S 47.859 µs 23.112 µs 51.7%
awsJson1_0_GetItemOutputBinary_M 140.018 µs 66.401 µs 52.6%
awsJson1_0_GetItemOutputBinary_L 816.823 µs 383.674 µs 53.0%
awsJson1_0_HealthcheckResponse_Example 10.684 µs 7.999 µs 25.1%

AWS JSON 1.1

Case Before p50 After p50 Improvement
awsJson1_1_GetItemOutput_Baseline 10.653 µs 8.067 µs 24.3%
awsJson1_1_GetItemOutput_S 45.079 µs 21.330 µs 52.7%
awsJson1_1_GetItemOutput_M 131.044 µs 59.105 µs 54.9%
awsJson1_1_GetItemOutput_L 764.908 µs 347.643 µs 54.6%
awsJson1_1_GetItemOutputBinary_S 47.176 µs 22.845 µs 51.6%
awsJson1_1_GetItemOutputBinary_M 140.314 µs 66.233 µs 52.8%
awsJson1_1_GetItemOutputBinary_L 815.806 µs 386.805 µs 52.6%
awsJson1_1_HealthcheckResponse_Example 10.711 µs 7.982 µs 25.5%

Compatibility

  • Existing codec APIs remain supported.
  • Streaming readers continue using incremental parsing by default.
  • Users can explicitly select STREAMING to retain the previous parser for buffered payloads.
  • Eager mode temporarily materializes the complete JSON value tree and is intended for buffered payloads where throughput is preferred.
  • Serialization behavior is unchanged.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Add automatic, eager, and streaming JSON deserialization modes and expose
the setting through generated JSON client configurations.
@stobrien89
stobrien89 force-pushed the json-eager-deserialization branch from 10bdb70 to df4c148 Compare October 13, 2026 21:07
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