Axel Le Pennec on Mastodon, noticed that using stored properties cause more recompilation when using Xcode Previews. In our discussion about this toot at work, a colleague suggested that while it’s likely that incremental builds are faster for computed properties, this might come with a performance hit.

I had a hunch that the compiler should almost certainly optimize away any extra costs associated with a computed properties that returns a constant.

To make a fairer comparison for cross-module compilation situations (like in a large real world app), consider the assembly generated from just this snippet (no main function, to simulate exposing this from a Framework):

public enum Constants {
    public static var computedProperty: Int { 3 }
    public static let storedProperty: Int = 3
}

Compiling with -Osize (optimize for executable size), we get the following relevant assembly:

static output.Constants.computedProperty.getter : Swift.Int:
        mov     w0, #3
        ret

output.Constants.storedProperty.unsafeMutableAddressor : Swift.Int:
        adrp    x0, (static output.Constants.storedProperty : Swift.Int)
        add     x0, x0, :lo12:(static output.Constants.storedProperty : Swift.Int)
        ret

static output.Constants.storedProperty.getter : Swift.Int:
        mov     w0, #3
        ret

The computed property generates exactly the same code for accessing the property in both cases: just a single mov instruction. The storedProperty also has an unsafeMutableAddressor that is generated. I’m not exactly sure what it does, but a colleague suggested that it is used for Swift’s borrow machinery, see e.g. this thread.