Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
Adding a return type slows execution down #2573
Adding a return type to a sub has significant execution impact:
Which apparently is the same as specifically specifying
So, are we cutting corners here when the return signature is
The reason I'm making this an issue as that I recently started to add a lot of missing return signatures to the core. Which had a very definite impact on the size of
Oddly enough, there is a benefit to specifying types on parameters:
Yes, we're taking that obvious easy optimization opportunity and just stripping out doing the check at all when the return type is
If we removed the optimization I just linked, I expect we'd see the same kind of numbers for
The obvious one for this particular case would be for the optimizer to spot that the value being returned will always match, and just not emit the type check bytecode sequence, much as it does in the
It turns out that if you add an argument to the sub, then the difference narrows quite a bit:
The reason seems to be that spesh mishandles zero-argument frames, producing a certain specialization rather than an observed type specialization, which in turn means the spesh plugin for return handling doesn't get fully optimized out. In an otherwise very tight loop, that will add up.
I think the significant thing about the
Returns were originally a sequence of two calls to Perl 6 extension ops: one for decontainerization, and one after that for return type checking. Those were both replaced a while back with a spesh plugin usage each, which is a short sequence of bytecode instructions, but certainly adds up when done in numerous places. This change let us fix longstanding bugs (the
In theory, it's possible to collapse the two return-handling spesh plugin resolutions/applications down into a single one, giving reduced bytecode size. In practice, it's not quite obvious how to do that and at the same time retain the static optimizations. It'll need some thought and experimentation. That'd give us a path to smaller code, though.
While we know spectest is about the worst case for optimization (very little code becomes hot), 4% is indeed a bit more than I'd have expected there. I wonder if the change impacted startup time a bit? I'll see if I can reproduce that effect locally once I get back to working on stuff after the New Year break. :-)
Let's keep it in there; we need to do it at some point anyway, and I think we'll be able to gain back a good amount of the performance (or it'll just get lost in wider improvements, which is also fine). It's useful for introspection purposes, and that is good for exploration, as well as for folks building things like auto-complete in IDEs that benefit from more complete type information in
FWIW, benchable (and confirmed by committable) found a significant slowdown introduced at a41c37c.
Which appears to confirm the size of the slowdown is a lot less if there are arguments passed to the block, as there always are with methods.