Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
This branch was previously deployed
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.
Cache the top-level JS field values checked while selecting a struct variant case, then decode the selected native value from that snapshot. This avoids reading those properties again in C++ variants, JNI sealed cases, and module-owned Swift structs. Ordinary typed struct calls keep their current converters.
Matching getters and proxy reads now run once and decoding uses the values observed during selection. Case order, mismatch short-circuiting and conversion-error propagation remain intact. Rejected cases create no native field values. Nested struct/collection checks retain their existing behavior. Imported Swift structs keep the previous path for compatibility with older generated dependencies; C++ and JNI detect preparation support at compile time.
First-match numeric structs take about 33% less time in the measured C++/Hermes workload; last-match structs take 24–32% less. Scalar and array controls are unchanged within the measured spread.
Reproducible benchmark source, raw samples and build commands: https://gist.github.com/mrousavy/4fa3d9ba78d44d8127a55269dba99d56
Benchmark method and environment
All times are ns per native variant decode, including selection and C++ result construction. Ratios pair the prepared decoder with the baseline from the same process/case/round; lower is faster. Five fresh processes ran seven measured rounds per case, giving 35 samples per option/case and 1,190 measured batches. Inputs were created outside timing. Both paths warmed up, shared one calibrated iteration count targeting a five-millisecond batch for the slower path, and ran in randomized order. A full Hermes GC preceded each batch, outside the timer. Every decoded result escaped through a compiler barrier; selected alternative and decoded-value checksums were checked outside timers.
The benchmark uses actual Nitrogen-generated native C++ structs, not a synthetic
canConvert/decode lambda.Before*converters come from the exact generator atcdaf72e60;After*converters come from the prepared-field implementation.BaselineVariant.hppis the exact old generic variant converter with only its class name changed so both implementations coexist in one executable. Structs have 2, 8 or 16 numeric fields per alternative. Inputs are immutable plain JS objects. First/last cases match their respective candidate; overlap matches both and must select the first; late rejection invalidates the first candidate's last field while the second matches; unmatched input invalidates the first candidate late and omits the second candidate's first field. Scalar and eight-number-array unions exercise unaffected decoder paths. Error cases include normal exception-message construction.Apple M2 Pro (arm64), macOS 27.2 (26B123), Apple clang 21.0.0 (clang-2100.4.1.1),
-std=c++20 -O3 -DNDEBUG. Hermes pinned commit26fbb82fad39d9d06901adb1d6d630dacc84c877, clean-source Release build, Hades GC,HEAP_HV_64, Unicode-lite, debugger/Intl disabled. Processes ran sequentially in an exclusive no-build window. These runtime measurements cover C++ struct/variant conversion through raw JSI/Hermes. Swift/JNI implementations have separate compilation/correctness coverage; they are not timed here.All variant benchmark cases
Validation: Nitrogen build, typecheck and lint pass; regenerating all four test packages is deterministic across 890 files. All 127 generated Android C++ translation units pass NDK syntax checks. External C++/Hermes fixtures pass ASan+UBSan checks for ordered matching, getters/proxies, rejected cases with side effects, selected-case conversion failures and cached references surviving forced GC. Hermes itself is an uninstrumented Release build. Real generated Swift/Hermes runtime checks pass for struct/array/primitive success, once-only getters, short-circuiting, throwing getters, selected-case failures and unmatched input. Legacy external Swift converter output is checked against the previous generator. All added fixtures and benchmarks stay outside the repository.