Skip to content

perf: defer SharedInfo allocation in ClassInfoCache.share()#68

Closed
bm1549 wants to merge 1 commit intomainfrom
brian.marks/opt-cache
Closed

perf: defer SharedInfo allocation in ClassInfoCache.share()#68
bm1549 wants to merge 1 commit intomainfrom
brian.marks/opt-cache

Conversation

@bm1549
Copy link
Copy Markdown
Contributor

@bm1549 bm1549 commented Apr 9, 2026

What Does This Do

Defer SharedInfo allocation in ClassInfoCache.share() until after the slot search completes. Also compare class names directly with className.equals() instead of via SharedInfo.equals(), which avoids creating a SharedInfo object just for the lookup.

Motivation

The original code eagerly allocates a SharedInfo wrapper before searching for a slot:

final SharedInfo update = new SharedInfo(className, info, classLoaderKeyId);
// ... search loop using update.equals() ...
shared[slot] = update;

When the class name already exists in the cache (the update-existing-entry path in share()), the allocation is done before the search even begins. Moving it after the search avoids the allocation overhead during the slot lookup, and comparing className.equals() directly is simpler than going through SharedInfo.equals().

Benchmark Notes

The existing ClassInfoCacheBenchmark exercises find() + share() in a loop, but after warmup all entries are cached so find() always succeeds and share() is never called on the hot path. This means the share() optimization is not measurable with this benchmark.

The improvement applies during cache population and when entries are being updated/evicted — not the steady-state lookup path that the benchmark measures.

Benchmark (singleThreaded) cacheSize=4096 cacheSize=16384
Baseline 8.41 ± 9.15 us/op 7.15 ± 2.46 us/op
After 6.61 ± 0.76 us/op 7.00 ± 2.74 us/op

Results are within noise for the steady-state path as expected. The allocation savings would be visible in a benchmark that continuously inserts new entries.

Additional Notes

  • Only share() is changed; find() is untouched
  • The share() parameter is String, so className.equals() is always valid
  • An earlier version also optimized find() with a String-specialized comparison, but this was dropped because callers may pass non-String CharSequence types (e.g. matching against method signatures or field descriptors)
  • All existing tests pass

Contributor Checklist

Jira ticket: N/A — performance optimization, no ticket

🤖 Generated with Claude Code

@mcculls mcculls self-requested a review April 9, 2026 16:22
Defer SharedInfo allocation until after slot search completes, avoiding
an unnecessary allocation when the class name already exists in the
cache. Also compare class names directly instead of via SharedInfo
.equals(), which avoids an intermediate object creation.

Note: find() is intentionally left using contentEquals(CharSequence)
since callers may pass non-String CharSequence types (e.g. when
matching against method signatures or field descriptors).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bm1549 bm1549 force-pushed the brian.marks/opt-cache branch from b8bddbb to 504a554 Compare April 9, 2026 17:40
@bm1549 bm1549 changed the title perf: optimize class-name comparison in ClassInfoCache.find() perf: defer SharedInfo allocation in ClassInfoCache.share() Apr 9, 2026
@bm1549
Copy link
Copy Markdown
Contributor Author

bm1549 commented Apr 9, 2026

Closing — on closer inspection the allocation is deferred but not eliminated, so there's no meaningful performance improvement. The original code structure is clearer.

@bm1549 bm1549 closed this Apr 9, 2026
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