Skip to content

fix: cache importstr and importbin values - #1094

Open
He-Pin wants to merge 3 commits into
databricks:masterfrom
He-Pin:perf/cache-raw-import-values
Open

fix: cache importstr and importbin values#1094
He-Pin wants to merge 3 commits into
databricks:masterfrom
He-Pin:perf/cache-raw-import-values

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

importstr and importbin rebuilt raw Jsonnet values on every visit, even though the resolved file was already cached. For large files this meant repeated disk reads and allocations.

Modification

  • Add per-evaluator importstr/importbin value caches keyed by resolved Path.
  • Clone importer-owned bytes on cache miss; store in compact ByteArr.
  • Add tests (one-read-per-kind, stable snapshots, aliasing, text/binary separation).
  • Add JMH benchmarks for repeated large imports.

Result

Workload Before (ms/op) After (ms/op) Speedup
repeated 256 KiB importbin x300 1062.9 0.2 ~5300x
repeated >1 MiB importstr x200 25.4 0.2 ~109x
single 256 KiB importbin 3.1 0.06 ~51x
repeated small importstr x300 0.174 0.171 neutral

Output correctness verified against go-jsonnet v0.22.0 and jrsonnet.

References

Motivation:
Repeated raw imports called ResolvedFile readers and rebuilt Jsonnet values on
every visit. Large importstr inputs could be read from disk repeatedly, while
importbin eagerly allocated one Eval entry per byte. This also failed to keep a
filename-stable raw-value snapshot for an evaluator.

Modification:
Cache importstr and importbin values independently by resolved path for the
lifetime of an Evaluator. Clone importer-owned binary data before storing it in
the compact ByteArr representation. Add snapshot, aliasing, cross-kind cache
tests, and controlled JMH workloads.

Result:
Stable importstr output remains identical across sjsonnet, go-jsonnet, and
jrsonnet; direct importbin output remains identical across sjsonnet and
go-jsonnet. Repeated 256 KiB importbin x300 improves from 1062.890 to 0.199
ms/op, and repeated >1 MiB importstr x200 improves from 25.394 to 0.232 ms/op
in the local JMH runs. Caches remain evaluator-local, so independent
Interpreter instances do not share raw imported values.

References:
- databricks#1094
- https://jsonnet.org/ref/spec.html
@He-Pin
He-Pin force-pushed the perf/cache-raw-import-values branch from f14ad61 to c1cfb5c Compare July 29, 2026 08:27
@He-Pin He-Pin changed the title Cache importstr and importbin values fix: cache importstr and importbin values Jul 29, 2026
@He-Pin
He-Pin marked this pull request as draft July 29, 2026 08:53
He-Pin added 2 commits July 29, 2026 17:43
Motivation:
The import cache shares ByteArr instances across all import sites.
rawBytes exposes the internal backing array by reference, so any
mutation would corrupt the cached value for all subsequent imports.

Modification:
Add CONTRACT comments to both ByteArr and LinearModByteArr rawBytes
overrides documenting that callers must not mutate the returned array.

Result:
Future contributors are warned about the shared-state invariant.
Motivation:
CI checkFormat failed on all platforms due to scaladoc comment style.

Modification:
Reformat multi-line scaladoc to match scalafmt 3.11.5 rules.

Result:
checkFormat passes on JVM/JS/Wasm/Native.
@He-Pin
He-Pin marked this pull request as ready for review July 29, 2026 10:26
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