Draft
Conversation
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Optimized JSON marshalling performance for JSON RPC and REST JSON protocols by replacing registry lookup and interface dispatch with a switch-based dispatch on MarshallingKnownType for payload fields, and caching the resolved marshaller on SdkField for non-payload fields.
Motivation and Context
Profiling of JSON RPC marshalling (used by DynamoDB, Lambda, etc.) identified two performance bottlenecks:
Megamorphic interface dispatch (8-16% self-time): The
marshaller.marshall(val, ctx, name, field)call site inmarshallFielddispatches throughJsonMarshaller<T>, an interface with 13+ implementations. The JIT sees many concrete types flowing through this single call site across loop iterations, making it megamorphic and preventing inlining.Redundant registry lookups (3-10% self-time): Every field marshalled goes through a multi-step registry lookup chain (
getMarshaller→ twoEnumMap.getcalls), even thoughSdkFieldinstances arestatic finaland the marshaller for a given(location, marshallingType)pair never changes.JMH benchmarks on representative DynamoDB workloads show 10-25% improvement in marshalling throughput, with the largest absolute wins on mixed-type and nested-structure payloads.
Modifications
SdkField.java(sdk-core):private volatile Objectfields (cachedMarshaller,cachedMarshallerRegistryKey) implementing a single-slot marshaller cache with reference-identity key comparison.cachedMarshallerandcacheMarshallerpublic methods.JsonProtocolMarshaller.java(aws-json-protocol):marshallPayloadField— a switch onMarshallingKnownTypethat handles all 16 known types. Simple types (STRING, INTEGER, LONG, etc.) are inlined as directStructuredJsonGenerator.writeValue()calls, giving the JIT monomorphic call sites it can inline. Composite types (SDK_POJO, LIST, MAP, DOCUMENT) and INSTANT delegate to the existingSimpleTypeJsonMarshallerconstants to avoid logic duplication. NullgetKnownType()and unrecognized values fall back to the registry path.doMarshallrouting: non-null PAYLOAD fields →marshallPayloadField(switch dispatch); non-null non-PAYLOAD fields →marshallFieldViaRegistry(cached registry); null non-PAYLOAD fields →marshallFieldViaRegistry(uncached, for null marshaller); null PAYLOAD + RequiredTrait → throws; null PAYLOAD + no RequiredTrait → no-op. Explicit payload handling (binary, string, JSON) is unchanged.Testing
New and existing unit tests + protocol tests.
Benchmark data
Data is from running standard SERDE tests from: #6860
Summary
The Big wins:
All data
Types of changes
Checklist
mvn installsucceedsscripts/new-changescript and following the instructions. Commit the new file created by the script in.changes/next-releasewith your changes.License