From 2067d8b5c488aa67f77477f2a94fd9eac166c652 Mon Sep 17 00:00:00 2001 From: He-Pin Date: Thu, 30 Apr 2026 12:02:09 +0800 Subject: [PATCH] perf: specialize Builtin1 and Builtin3 apply paths Motivation: Reduce allocation and dispatch overhead when one- and three-argument builtins are called through the dynamic function apply path. Modification: Add Builtin1.apply1 and Builtin3.apply3 overrides that directly call their structured evalRhs methods for exact positional arity, matching the existing Builtin2.apply2 specialization and falling back to the generic parent path otherwise. Result: Dynamic builtin calls avoid constructing temporary argument arrays on the exact-arity path. JVM tests and targeted hyperfine comparisons pass. --- sjsonnet/src/sjsonnet/Val.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sjsonnet/src/sjsonnet/Val.scala b/sjsonnet/src/sjsonnet/Val.scala index c87a56c0..0cf1efab 100644 --- a/sjsonnet/src/sjsonnet/Val.scala +++ b/sjsonnet/src/sjsonnet/Val.scala @@ -1906,6 +1906,12 @@ object Val { tailstrictMode: TailstrictMode): Val = if (namedNames == null && argVals.length == 1) evalRhs(argVals(0).value, ev, outerPos) else super.apply(argVals, namedNames, outerPos) + + override def apply1(argVal: Eval, outerPos: Position)(implicit + ev: EvalScope, + tailstrictMode: TailstrictMode): Val = + if (params.names.length == 1) evalRhs(argVal.value, ev, outerPos) + else super.apply(Array(argVal), null, outerPos) } abstract class Builtin2(fn: String, pn1: String, pn2: String, defs: Array[Expr] = null) @@ -1949,6 +1955,13 @@ object Val { if (namedNames == null && argVals.length == 3) evalRhs(argVals(0).value, argVals(1).value, argVals(2).value, ev, outerPos) else super.apply(argVals, namedNames, outerPos) + + override def apply3(argVal1: Eval, argVal2: Eval, argVal3: Eval, outerPos: Position)(implicit + ev: EvalScope, + tailstrictMode: TailstrictMode): Val = + if (params.names.length == 3) + evalRhs(argVal1.value, argVal2.value, argVal3.value, ev, outerPos) + else super.apply(Array(argVal1, argVal2, argVal3), null, outerPos) } abstract class Builtin4(