Should I cache a computed variable to be used in loops?

I have a computed value which I know won't change during a loop. Should I cache that value so it isn't computed repeatedly, or does the swift compiler take care of this?

Below is an example. Would process1 and process2 be optimized to be the same?

class MyClass {

    var enableMode: Bool = true

    var modeValue: Int {
        enableMode ? 10 : 20 
    }

    func process1(values: [Int]) -> Int {
        let cachedModeValue = self.modeValue
        var processedValue = 0
        for val in values {
            processedValue += cachedModeValue * val
        }
        return processedValue
    }

    func process2(values: [Int]) -> Int {
        var processedValue = 0
        for val in values {
            processedValue += modeValue * val
        }
        return processedValue
    }

}

While the example is simple, my actual functions have a lot more computation.

1 Like

The most reliable way to get the behavior you want is to cache the value yourself. The compiler can recognize when a function always produces the same result and hoist it out of loops for you, but it's difficult to give an exact account of all the conditions it will do so, and you may not want to rely on it.

9 Likes

Instant answer! In general I rather let the compiler do its job, but I'm just not familiar with its latest abilities. Should I learn the conditions? (Where could I find them?) Do you have any general guidance on avoiding over optimizing?

To me, assigning the results of computed properties or functions to local variables isn't an "over-optimization"; it can also help readability, since someone reading the code doesn't need to think about whether the computed property has side effects that might run multiple times.

9 Likes

This is why the gods gave us capture lists! :zap:

values.reduce(0) { [modeValue] in $0 + modeValue * $1 }
values.reduce(0) { [cachedModeValue = modeValue] in $0 + cachedModeValue * $1 }
9 Likes

Cool, I've never really seen capture lists used for anything other than weak capturing self.

1 Like