Skip to content

Commit e10ccc6

Browse files
authored
perf: abstract FormatCache as pluggable trait, optimize format runtime (#679)
## Motivation The `%` format operator in Jsonnet is commonly used in string-heavy workloads (e.g., realistic2). Each format call re-parses the format string, which is wasteful when the same format pattern is used repeatedly. ## Key Design Decision Abstract format string parsing into a `FormatCache` trait, allowing parsed format specifications to be cached and reused across calls. The default implementation provides a simple LRU-style cache. ## Modification - Add `FormatCache` trait with pluggable cache strategy - Cache parsed format specifications keyed by format string - Optimize format runtime dispatch for common patterns - ~317 lines changed ## Benchmark Results ### JMH (JVM, 3 iterations warmup + 3 measurement) | Benchmark | Master (ms/op) | This PR (ms/op) | Change | |-----------|---------------|-----------------|--------| | bench.02 | 50.427 ± 38.9 | 45.984 ± 2.4 | **-8.8%** | | comparison2 | 85.854 ± 188.7 | 69.734 ± 19.9 | **-18.8%** | | realistic2 | 73.458 ± 66.7 | 70.857 ± 3.2 | **-3.5%** | ## Analysis The format cache helps most on comparison2 (-18.8%) which has repeated format patterns. The realistic2 improvement is modest (-3.5%) because its format patterns have more variety. The infrastructure enables further optimizations on format-heavy workloads. ## References - Upstream: jit branch experiment ## Result All 5 tests pass. All benchmarks positive, no regressions.
1 parent cfbb1a1 commit e10ccc6

6 files changed

Lines changed: 317 additions & 104 deletions

File tree

sjsonnet/src-jvm-native/sjsonnet/SjsonnetMainBase.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ object SjsonnetMainBase {
373373
logger = warnLogger,
374374
std = std,
375375
variableResolver = _ => None,
376-
debugStats = debugStats
376+
debugStats = debugStats,
377+
formatCache = FormatCache.SharedDefault
377378
) {
378379
override def createEvaluator(
379380
resolver: CachedResolver,

sjsonnet/src/sjsonnet/Evaluator.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class Evaluator(
2222
val wd: Path,
2323
val settings: Settings,
2424
logger: Evaluator.Logger = null,
25-
val debugStats: DebugStats = null)
25+
val debugStats: DebugStats = null,
26+
override val formatCache: FormatCache = FormatCache.SharedDefault)
2627
extends EvalScope {
2728
implicit def evalScope: EvalScope = this
2829
def importer: CachedImporter = resolver
@@ -1270,8 +1271,9 @@ class NewEvaluator(
12701271
private val w: Path,
12711272
private val s: Settings,
12721273
private val wa: Evaluator.Logger = null,
1273-
ds: DebugStats = null)
1274-
extends Evaluator(r, e, w, s, wa, ds) {
1274+
ds: DebugStats = null,
1275+
fc: FormatCache = FormatCache.SharedDefault)
1276+
extends Evaluator(r, e, w, s, wa, ds, fc) {
12751277

12761278
override def visitExpr(e: Expr)(implicit scope: ValScope): Val = try {
12771279
(e.tag: @switch) match {

0 commit comments

Comments
 (0)