You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the default implementations of the various `_failEarlyRangeCheck` forms contain several _precondition invocations, like this:
```
@inlinable
public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {
_precondition(
bounds.lowerBound <= index,
"Out of bounds: index < startIndex")
_precondition(
index < bounds.upperBound,
"Out of bounds: index >= endIndex")
}
```
Each such precondition call generates a separate trap instruction, which seems like a waste — theoretically it would be helpful to know which condition was violated, but in practice, that information tends not to be surfaced anyway. Combining these will lead to a minuscule code size improvement.
(The separate messages do surface these in debug builds, but only if these generic defaults actually execute, which isn’t often. These are not public entry points, so concrete collection types tend ignore these and roll their own custom index validation instead. From what I’ve seen, custom code tends to combine the upper/lower checks into a single precondition check. These underscored requirements tend to be only called by the standard `Slice`; and it seems reasonable for that to follow suit.)
More interestingly, the range-in-range version of `_failEarlyRangeCheck` performs two times as many checks than are necessary:
```
@inlinable
public func _failEarlyRangeCheck(_ range: Range<Index>, bounds: Range<Index>) {
_precondition(
bounds.lowerBound <= range.lowerBound,
"Out of bounds: range begins before startIndex")
_precondition(
range.lowerBound <= bounds.upperBound,
"Out of bounds: range ends after endIndex")
_precondition(
bounds.lowerBound <= range.upperBound,
"Out of bounds: range ends before bounds.lowerBound")
_precondition(
range.upperBound <= bounds.upperBound,
"Out of bounds: range begins after bounds.upperBound")
}
```
It is safe to assume that `range.lowerBound <= range.upperBound`, so it’s enough to test that `bounds.lowerBound <= range.lowerBound && range.upperBound <= bounds.upperBound` — we don’t need to check each combination separately.
0 commit comments