Will simple "non-computing" computed properties always be optimized away?

Let's say we have this:

struct Disk {
    var center: SIMD2<Float>
    var radius: Float
}

And we decide to reduce visual clutter in Disk's methods by providing shorter names for center and radius like so:

extension Disk {
    private var c: SIMD2<Float> { return center }
    private var r: Float { return radius }
}

Question: In our optimized builds, can using c and r instead of center and radius ever result in less efficient code?

(My assumption is that it should not make any difference at all to the resulting binary.)

Also, would it be different if c and r were internal or public instead of private?

If you make them public then I believe you need @inlinable (or @_transparent) to let client code optimize them.

Within the same compilation unit where they are defined, the compiler should be able to see through them.

I’m not sure about uses from other files in the same module without whole-module optimization.

…and I don’t know if anything is actually guaranteed in this arena.

4 Likes

@Nevin is correct, and in particular you should note the important caveat that nothing is guaranteed here.

In general, however, the cost of a simple function call to return a trivial computed property is not a huge concern. Straightforward function calls are pretty cheap. The risks here occur when either a) inlining the function unlocks further optimisation opportunities (usually when the computed property statically returns a single value that can be constant-folded, but sometimes with ARC and other things) or b) when your computed property is defined on a generic object and so must be dispatched generically. In both of those cases it is worthwhile trying to avoid the function call with @inlinable (note the ABI risks here). Otherwise, I wouldn't worry about it.

And within the same module with WMO you can ignore all of this, as everything is always visible to the compiler.

2 Likes