[swift-evolution] Compiler Optimization of Optional-returning Functions followed by '!'

Joe Groff jgroff at apple.com
Thu Jan 19 16:35:27 CST 2017


> On Jan 19, 2017, at 2:17 PM, Jonathan Hull via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi all,
> 
> I would like to propose an optimization to the compiler where, when a call to an optional-returning function is immediately followed by a ‘!’, we allow the compiler to generate an alternate version of the function where a trap replaces 'return nil’ and the function returns a non-optional result.  This would save the build-up and tear-down cost of the optional.
> 
> Is this possible?
> 
> 
> The main reason I would want this is to be able to later propose moving our default array index handling to a safer optional-returning version.  I know that a safe variant is on the horizon, but defaults really matter… especially with newcomers to the language.  Array indexing should return an optional, forcing the programmer to deal with an out-of-bounds case appropriately. Where the current behavior is desired, the access is immediately followed by a ‘!’ indicating the potential crash-point explicitly in code.  Migration would simply add a ‘!’ after every array subscript access. The above proposal is meant to mitigate any performance issues from the change, because the generated function for the cases followed by ‘!’ would be identical to the current version.
> 
> It should also have a good effect on runtime performance for any place in code where a function result is immediately force unwrapped...

There are other reasons collection indexing doesn't return Optional besides performance; there have been a number of threads on this topic in the past already. I'd be surprised if building an optional were really all that expensive to begin with—the binary representation of '.some(x)' inside an Optional is always the same as 'x', with at most a zero byte tacked on the end. Checking an optional in turn only needs to check for an invalid representation of x (like a null pointer) or check that that extra bit is unset.

-Joe


More information about the swift-evolution mailing list