perf: add rendered key byte cache in ByteRenderer - #1118
Draft
He-Pin wants to merge 2 commits into
Draft
Conversation
Motivation:
Object keys are rendered (quoted + escaped) on every materialization.
In K8s manifests and similar workloads, the same short keys ("apiVersion",
"kind", "metadata", "spec") repeat thousands of times across objects.
Each render re-runs getChars + escape scan unnecessarily.
Modification:
- 64-slot identity-keyed cache for quoted object key bytes
- Cache hit: System.arraycopy pre-rendered bytes (zero escape scan)
- Cache miss: render normally, populate if key.length <= 32
- Keys > 64 chars bypass cache entirely (rare, not worth caching)
- Identity-keyed (eq) so no hashCode/equals overhead on lookup
Result:
MainBenchmark: 3.028 → 3.197 ms/op (within noise ±1.9, no regression)
All 424 tests pass. The cache synergizes with identifier interning
(separate PR) which guarantees stable String identity for field names,
maximizing hit rate.
He-Pin
marked this pull request as draft
August 12, 2026 05:34
Motivation: Keys 33-64 chars passed the bypass check (> 64) but were never stored (populate guard <= 32), causing wasted cache lookups on every render. Modification: Lower KeyCacheMaxKeyLength to 32 and remove the redundant populate guard. Keys > 32 now bypass the cache entirely. Result: Eliminates dead lookup paths; simpler control flow with identical caching behavior for keys <= 32.
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.
Motivation
Object keys are rendered (quoted + escaped) on every materialization. In K8s manifests and similar workloads, the same short keys (
apiVersion,kind,metadata,spec) repeat thousands of times across objects. Each render re-runsgetChars+ escape scan unnecessarily.Modification
ByteRendererSystem.arraycopypre-rendered bytes (zero escape scan)key.length <= 32eq) so nohashCode/equalsoverhead on lookupResult
JMH config:
-f 2 -wi 5 -i 10 -w 1 -r 1The
stdlib.jsonnetbenchmark has limited key repetition; the cache's primary benefit is in K8s-style manifests with high key reuse. Synergizes with identifier interning (#1117) which guarantees stable String identity for field names, maximizing cache hit rate.All 424 tests pass.
Test plan
./mill 'sjsonnet.jvm[_]'.test— all pass./mill bench.runJmh ".*MainBenchmark.*"— no regression