Skip to content

Allocate shape metadata on first write (3,800 fewer empty Hashes when loading S3 and KMS) - #3491

Open
czj wants to merge 1 commit into
aws:version-3from
czj:perf/lazy-shape-metadata
Open

czj wants to merge 1 commit into
aws:version-3from
czj:perf/lazy-shape-metadata

Conversation

@czj

@czj czj commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Every Seahorse::Model::Shapes::Shape and ShapeRef creates an empty metadata Hash in initialize, though most of them never get any metadata. This creates it on the first []= instead, and [] reads a missing Hash as no metadata. It's a small one, next to #3465: about 0.6 MB less per process for S3 and KMS, and the same for every other service API an app loads.

Loading the S3 and KMS APIs (ClientApi::API), on version-3 at 1419898 and with this change, Ruby 4.0.9:

version-3 this PR
unfrozen empty Hashes left after load 4,186 353
objects allocated while loading 200,783 196,950
ObjectSpace.memsize_of_all 6.06 MB 5.48 MB

Load time doesn't change (within noise, interpreter and YJIT). Query-protocol responses (STS, SQS, SNS, IAM) also allocate 3 Hashes less each, since Query::Handler#rules builds a shape and two refs per response.

Every metadata read on the S3 and KMS models (4,273 shape, ref and operation reads over 27 keys, including one that is never set) gives the same values before and after. aws-sdk-core (2,496 examples) and aws-sdk-s3 (1,721) specs pass, and the new spec covers reading metadata that was never set.

Operation and Api keep their eager Hash, there are only a few of them. Would you like those changed too for consistency, or is it fine to keep this one narrow?

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Generated with Claude Code, but prompted, read, and verified by @czj, a caring human :)

Every Shape and ShapeRef created an empty metadata Hash, though most never get any metadata. Loading the S3 and KMS APIs left 3,833 of them, about 0.6 MB of Ruby objects. Create the Hash on the first []= instead; [] reads nil as no metadata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@czj
czj requested review from a team as code owners November 6, 2026 08:56
@czj
czj requested review from jterapin and siddsriv November 6, 2026 08:56
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