perf: valTag dispatch for O(1) materializer type routing#682
Open
He-Pin wants to merge 1 commit intodatabricks:masterfrom
Open
perf: valTag dispatch for O(1) materializer type routing#682He-Pin wants to merge 1 commit intodatabricks:masterfrom
He-Pin wants to merge 1 commit intodatabricks:masterfrom
Conversation
Add a valTag: Byte abstract method to Val with TAG constants (0-7) for each concrete subclass, enabling JVM tableswitch O(1) dispatch in the materializer instead of linear pattern matching. Changes: - Val.scala: Add valTag abstract method and TAG_STR/NUM/TRUE/FALSE/NULL/ ARR/OBJ/FUNC constants (0-7 contiguous range) - Materializer.scala: Replace pattern-match in materializeRecursiveChild with @switch tableswitch dispatch on valTag. Hoist xs.length out of materializeRecursiveArr while-loop. - CustomValTests.scala: Add valTag=-1 to ImportantString (custom Val) JMH improvements: reverse -2.9%, base64DecodeBytes -4.6%, comparison2 -1.9%, base64 -2.1%. No regressions outside noise range. Upstream: he-pin/sjsonnet jit branch commits 30b7495, 9ddb1a5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The
materializeRecursiveChildmethod inMaterializer.scaladispatches onValsubtype using a Scala pattern match, which compiles to sequentialinstanceofchecks. For 8 concreteValsubtypes, this means up to 7 type tests before reaching the correct branch. This is the hot path for all JSON materialization.Key Design Decision
Introduce a
valTag: Bytefield on eachValsubclass with contiguous values 0-7, enabling@switchannotation to generate JVMtableswitchbytecode for O(1) dispatch. Verified withjavap -cthat the bytecode is:Custom
Valsubclasses (e.g.Materializable) usevalTag = -1and fall through to a nested pattern match in the default branch.Modification
Val.scala: Addedprivate[sjsonnet] def valTag: Byteabstract method tosealed abstract class Val. Added TAG constants (TAG_STR=0throughTAG_FUNC=7). Every concrete subclass overridesvalTag.Materializer.scala: Replaced pattern-match dispatch inmaterializeRecursiveChildwith@switchtableswitch dispatch. Added null guard beforevalTagaccess to preserve original diagnostic. Hoistedxs.lengthout ofmaterializeRecursiveArrwhile-loop.CustomValTests.scala: AddedvalTag: Byte = -1to testImportantStringclass.Benchmark Results
JMH (35 benchmarks, single-threaded)
Zero regressions across all 35 benchmarks.
Native (hyperfine, 10 runs)
Native impact is neutral (within noise) — the primary value is architectural: tableswitch enables future materializer optimizations to benefit from O(1) dispatch.
Analysis
References
30b7495b(valTag dispatch) and9ddb1a57(tableswitch dispatch)Result
All 140 tests pass.
@switchtableswitch bytecode verified viajavap -c. No regressions.