Swift Nil-coalescing Performance Trap
Ben Cohen (via Ole Begemann):
?? []is a significant performance and correctness trap.Not because
[]creates an array unnecessarily (it doesn’t, the empty array is a static singleton in the standard library via a performance hack that gives me heartburn).It’s because when the array isn’t
nil, the presence of?? []affects the type checker in ways you don’t expect[…][…]
So what does
maybeHugeRange?.reversed() ?? []do? TheReversedCollectionanswer won’t type check, because the rhs of??can’t be one. So instead it falls back to the version on forward-only collections. That returns an array. So now, just because of that?? [], we are attempting to allocate and fill an array of sizeInt.max. Which blows up.
This proposal introduces optional iteration (
for?) and hence the possibility to use optional sequences as the corresponding attribute infor-inloops.[…]
The
?notation here is a semantic emphasis rather than a functional unit: there is nofor!. Syntactically marking an optional iteration is redundant, however, in constrast toswitch, nil values are skipped silently. Swift strives to follow a style where silent handling ofnilis acknowledged via the?sigil, distinctly reflected in optional chaining. This decision was primarily based on inconsistency and potential confusion that an otherwise left without syntactic changesfor-inloop could potentially lead to (“clarity over brevity”).