-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
There are quite a few places in the Framework where we have specialized knowledge of data structures and algorithms - beyond what the JIT has - where we'd be able to make optimizations beyond what the JIT can provide if the JIT is able to hint to us information about locals.
For example, consider string.StartsWith(char) : bool
, which is currently implemented as below.
public bool StartsWith(char value) => Length != 0 && _firstChar == value;
If the JIT were able to hint to us information about the local, we could write this as follows, which would allow us to elide the first branch entirely in almost all cases, taking advantage of the fact that empty strings have the null-terminator in the _firstChar
position.
public bool StartsWith(char value) {
if (JitHelpers.IsKnownConstant(value) && value != 0) {
return _firstChar == value;
} else {
return Length != 0 && _firstChar == value;
}
}
It would also allow us to further optimize the Span.Slice(int start, int length)
logic we checked in earlier, which allows us to do something akin to the below.
if (JitHelpers.IsKnownConstant(start)) {
if (start == 0) {
// case Slice(0, <something>)
ThrowIf((uint)length > (uint)_realLength);
return <slice>;
} else if (JitHelpers.IsKnownConstant(length) && start >= 0 && length >= 0) {
// case Slice(10, 20)
ThrowIf((uint)(start + length) > (uint)(_realLength));
return <slice>;
}
}
ThrowIf(normal_validation_checks);
return <slice>;
This could also have potential applications for methods which are implemented via a giant switch statement which normally doesn't get inlined (see String.Equals(..., StringComparison)
overload). We could choose to implement the method as an inlineable method that does a very fast dispatch if the comparison parameter is known constant, falling back to a slower non-inlined method if the comparison parameter needs to be evaluated at runtime.
The behavior of IsKnownConstant
would be such that the JIT would replace it with true if the value is known at JIT time to be constant (perhaps because it is itself a literal or has been calculated from some other const-folding). It would be replaced with false in all other cases, including if the JIT simply doesn't have enough information to make a determination, or if optimizations have been disabled. I'm also assuming branch pruning would kick in to completely elide code that is on the incorrect side of the IsKnownConstant
check.
category:proposal
theme:optimization
skill-level:expert
cost:extra-large