Skip to content

perf: add rendered key byte cache in ByteRenderer - #1118

Open
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:perf/rendered-key-byte-cache
Open

perf: add rendered key byte cache in ByteRenderer#1118
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:perf/rendered-key-byte-cache

Conversation

@He-Pin

@He-Pin He-Pin commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

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 in ByteRenderer
  • Cache hit: System.arraycopy pre-rendered bytes (zero escape scan)
  • Cache miss: render normally, populate slot 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

Benchmark master this PR Delta
MainBenchmark.main 3.028 ± 0.536 ms/op 3.197 ± 1.924 ms/op within noise

JMH config: -f 2 -wi 5 -i 10 -w 1 -r 1

The stdlib.jsonnet benchmark 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

@He-Pin
He-Pin marked this pull request as draft August 12, 2026 05:34
@He-Pin
He-Pin force-pushed the perf/rendered-key-byte-cache branch from 67a4a30 to 951a999 Compare August 20, 2026 12:12
Motivation:
Object keys are rendered (quoted + escaped) on every materialization.
In K8s manifests and similar workloads, the same short keys repeat
thousands of times. Each render re-runs getChars + escape scan.

Modification:
- 64-slot identity-keyed cache for quoted object key bytes
- Two-touch pattern: store key on first sight, capture bytes on second
  identity hit (avoids byte[] allocation for one-shot keys)
- Cache hit: System.arraycopy pre-rendered bytes (zero escape scan)
- Keys > 32 chars bypass cache entirely (rare, not worth caching)
- Identity-keyed (eq) so no hashCode/equals overhead on lookup
- Lazy initialization avoids allocation for small outputs

Result:
MainBenchmark: within noise (no regression). The cache synergizes
with identifier interning (databricks#1117) which guarantees stable String
identity for field names, maximizing hit rate.
@He-Pin
He-Pin force-pushed the perf/rendered-key-byte-cache branch from 2566966 to fb4c2ad Compare August 22, 2026 09:33
@He-Pin
He-Pin marked this pull request as ready for review August 22, 2026 09:33
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