Skip checking block type in sorbet-runtime when possible #6487
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
Runtime performance
Benchmarks
I've collected these before fixing the aforementioned problems with
nil
, soit's possible that these benchmarks will get slower after that.
Only the bolded things should get sped up from this change—other changes are included to showcase how noisy the measurements usually are. Speedups are reported as percentage speedups vs "Before" (so negative percents are slowdowns—some things slow down by small percentages due to noise in measurement).
nil
checksnil
checks{}
&blk
{}
&blk
Update
I pushed a change to make the optimization also combine with the existing fast path optimizations (because those validators already skip the block type checking, so when the method mentions a
&blk
parameter but there is no need to check the block type, we can still take the fast path validators). As expected, the fast path validators are quite fast.nil
and take fast path if possibleThis makes passing a
{}
block within 50% of no block, and passing a&blk
block within 15% of no block.Analysis
Oddly, the "without
nil
checks" times are actually faster than the initial implementation that did not check and report a sorbet-runtiem error fornil
. I take that to mean that there is likely, there is no additional performance gained by skipping thenil
checking when possible, but I figure we may as well keep the separate code paths, because it also means that there's not a penalty to doing so.Test plan
See included automated tests.
old, outdated initial description
Leaving this as work-in-progress, because the one thing that the VM doesn't do
that Sorbet does do currently is check whether a block was required.
One approach would be to only skip this check for methods whose block is typed
as
T.nilable(...)
, and simply leave the old behavior otherwise.Another approach would be to do something like the
create_validator_fast
methods that skips checking block types for all methods (not just those that
have a certain arity) depending on whether they take a block or not.