Skip to content

perf: cached renderDouble for small integers + Builtin1/3 apply overrides#763

Draft
He-Pin wants to merge 1 commit intodatabricks:masterfrom
He-Pin:perf/cached-render-double
Draft

perf: cached renderDouble for small integers + Builtin1/3 apply overrides#763
He-Pin wants to merge 1 commit intodatabricks:masterfrom
He-Pin:perf/cached-render-double

Conversation

@He-Pin
Copy link
Copy Markdown
Contributor

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

Motivation

RenderUtils.renderDouble is called on every number materialization. Small integer values (0-255) are common in Jsonnet workloads (array indices, ASCII codepoints, counters), so caching their string representations avoids repeated Long.toString allocation.

Builtin1 and Builtin3 were also missing direct apply1 / apply3 overrides while Builtin2 already had apply2, leaving avoidable intermediate Array allocation on those builtin calls.

Key Design Decision

  1. Cache string representations for integer values 0-255 in RenderUtils.
  2. Reuse renderDouble from Materializer.stringify so number rendering has one fast path.
  3. Add direct apply1 and apply3 overrides for Builtin1 and Builtin3, matching the existing Builtin2.apply2 pattern.

Modification

  • Renderer.scala: add a small integer string cache and use it when rendering non-negative integral doubles in range 0-255.
  • Materializer.scala: delegate numeric stringification to RenderUtils.renderDouble instead of duplicating integer handling.
  • Val.scala: add apply1 override to Builtin1 and apply3 override to Builtin3.

Benchmark Results

No benchmark was remeasured in this rebase/test cycle. Targeted benchmark work is deferred to the later serial benchmark batch.

Prior directional evidence from this PR:

Benchmark Master (ms/op) This PR (ms/op) Change
manifestTomlEx 0.074 0.069 -6.8%
realistic2 57.139 58.868 +3.0% noise
large_string_template 1.610 1.646 +2.2% noise

Prior wider JMH sweep summary: 7 improvements, 8 regressions, 20 neutral on Apple Silicon single-shot average. Treat as directional only.

Analysis

The integer cache removes allocation for the hot 0-255 rendering range while preserving the existing rendering semantics for other numbers. The builtin apply overrides remove avoidable argument-array allocation and follow an existing code pattern. The current cycle was limited to safe rebase, formatting, full test validation, PR body normalization, and protected branch update.

References

  • Upstream source commit: 9917a682
  • Rebased onto upstream/master fd1b3b1e

Result

Rebase completed cleanly onto upstream/master. Validation in this cycle:

  • rtk ./mill __.reformat: SUCCESS; worktree remained clean.
  • rtk ./mill __.test: SUCCESS.

@He-Pin He-Pin force-pushed the perf/cached-render-double branch from 12b870c to 4c8c5ab Compare April 12, 2026 17:32
@He-Pin He-Pin marked this pull request as ready for review April 12, 2026 17:48
@He-Pin He-Pin marked this pull request as draft April 12, 2026 18:57
@He-Pin He-Pin force-pushed the perf/cached-render-double branch from 4c8c5ab to 93acd93 Compare April 25, 2026 06:17
…ides

Three optimizations:
1. RenderUtils.renderDouble: pre-cached string representations for
   integers 0-255, avoiding Long.toString allocation on every call.
2. Materializer.stringify: unified with renderDouble (removes duplicate
   integer fast-path code).
3. Builtin1.apply1 / Builtin3.apply3: added direct override methods
   that call evalRhs without creating intermediate Array.

Upstream: jit branch commit 9917a68
@He-Pin He-Pin force-pushed the perf/cached-render-double branch from 93acd93 to 3ae5a56 Compare April 25, 2026 08:32
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