Skip to content

Skip EnhancedAttributeValue wrapping in converters transformTo when t… - #6707

Merged
RanVaknin merged 5 commits into
masterfrom
rvaknin/ddb-optimization-converters
Mar 10, 2026
Merged

Skip EnhancedAttributeValue wrapping in converters transformTo when t…#6707
RanVaknin merged 5 commits into
masterfrom
rvaknin/ddb-optimization-converters

Conversation

@RanVaknin

@RanVaknin RanVaknin commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

The Enhanced Client processes every DynamoDB Enhanced client operation through a conversion pipeline that transforms between AttributeValue and Java POJOs. This optimization targets the deserialization path where responses from DynamoDB are converted back into Java objects.

Current Approach (Before Optimization)

Our current approach for deserialization codepaths (transformTo method) wraps every AttributeValue in an EnhancedAttributeValue, even when no type conversion is needed:

public class StringAttributeConverter implements AttributeConverter<String> {
    @Override
    public String transformTo(AttributeValue input) {
        // Always wraps, even for String -> String
        return EnhancedAttributeValue.fromAttributeValue(input).convert(TypeConvertingVisitor.INSTANCE);
    }
}

The problem is that for the common case where types already match (String→String, Bytes→byte[]), we're creating unnecessary wrapper objects and going through the visitor pattern.

Optimized Approach (After)

Short-circuit the common case where no type conversion is needed:

public class StringAttributeConverter implements AttributeConverter<String> {
    @Override
    public String transformTo(AttributeValue input) {
        if (input.s() != null) {
            return input.s();  // Fast path
        }
        // Slow path: type conversion (Number->String, Boolean->String, etc.)
        return EnhancedAttributeValue.fromAttributeValue(input).convert(TypeConvertingVisitor.INSTANCE);
    }
}

Scope of Optimization

This optimization applies to scalar type converters where the DynamoDB type directly maps to the Java type:

  • StringAttributeConverter (String → String) (covered in this PR)
  • ByteArrayAttributeConverter (Bytes → byte[]) (covered in this PR)

Not covered in the PR because not included in the Datasets. Will likely benefit the same way but harder to prove without more data:

  • BooleanAttributeConverter (Boolean → Boolean)
  • ByteBufferAttributeConverter (Bytes → ByteBuffer)
  • SdkBytesAttributeConverter (Bytes → SdkBytes)

Cannot be optimized:

  • Collection converters (List, Map, Set) - must recursively convert nested elements, requiring the visitor pattern to handle arbitrary nesting and type conversions
  • Number converters (Integer, Long, Double, etc.) - DynamoDB's wire format stores numbers as strings (e.g., {"N": "123"}). The converter must parse this string representation regardless of whether we short-circuit the wrapper. Since input.n() returns "123" (a String), not 123 (an Integer)

Flamegraphs (Get SMALL):

Before:

image

After:

image

Benchmarks:

Operation Size V2 Master Mean (us/op) optimized Improvement
Delete TINY 0.425 0.388 9.54%
Delete SMALL 0.413 0.422 -2.13%
Delete HUGE 0.411 0.402 2.24%
Delete HUGE_FLAT 0.407 0.4 1.75%
Get TINY 0.471 0.445 5.84%
Get SMALL 1.001 0.896 11.72%
Get HUGE 10.256 9.048 13.35%
Get HUGE_FLAT 3.075 2.863 7.40%
Put TINY 0.746 0.717 4.04%
Put SMALL 1.346 1.37 -1.75%
Put HUGE 13.449 13.194 1.93%
Put HUGE_FLAT 8.236 7.855 4.85%
Query TINY 2.544 2.371 7.30%
Query SMALL 4.273 3.74 14.25%
Query HUGE 30.658 30.639 0.06%
Query HUGE_FLAT 8.884 9.05 -1.83%
Scan TINY 1.088 0.928 17.24%
Scan SMALL 2.604 2.274 14.51%
Scan HUGE 29.882 27.949 6.92%
Scan HUGE_FLAT 8.496 7.778 9.23%
Update TINY 1.372 1.317 4.18%
Update SMALL 9.324 9.118 2.26%
Update HUGE 39.691 39.114 1.48%
Update HUGE_FLAT 241.643 237.085 1.92%

@RanVaknin
RanVaknin marked this pull request as ready for review February 6, 2026 22:36
@RanVaknin
RanVaknin requested a review from a team as a code owner February 6, 2026 22:36
@RanVaknin RanVaknin added changelog-not-required Indicate changelog entry is not required for a specific PR no-api-surface-area-change Indicate there is no API surface area change and thus API surface area review is not required labels Feb 6, 2026
@RanVaknin
RanVaknin force-pushed the rvaknin/ddb-optimization-converters branch from 8536844 to 114a939 Compare February 17, 2026 21:26

@zoewangg zoewangg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worth adding changelog entry?

@RanVaknin RanVaknin removed the changelog-not-required Indicate changelog entry is not required for a specific PR label Feb 26, 2026
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
30.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@RanVaknin
RanVaknin added this pull request to the merge queue Mar 10, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Mar 10, 2026
@RanVaknin
RanVaknin added this pull request to the merge queue Mar 10, 2026
Merged via the queue into master with commit a629877 Mar 10, 2026
54 of 55 checks passed
@github-actions

Copy link
Copy Markdown

This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Mar 10, 2026
@RanVaknin
RanVaknin deleted the rvaknin/ddb-optimization-converters branch May 18, 2026 22:17
@RanVaknin RanVaknin added the perf-improvement Label for PRs that contain performance improvement changes. label May 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

no-api-surface-area-change Indicate there is no API surface area change and thus API surface area review is not required perf-improvement Label for PRs that contain performance improvement changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants