Atelier Clockwork

Improving Swift Build Times

Because Sometimes the Compiler Gets Lost

Building a large Swift project gets a little slow. To some degree, it’s just the problem that the compiler is doing a lot of work, but there are times when compiler has a hard time with a function, and compile time goes up from the reasonable range of under 100ms to several seconds. I followed one of the basic guides to profiling compile times and found that my current project had a worst offender in the 7 seconds range:

func differenceFrom(otherRGBA: UIImage.RGBA) -> Int {
   return Int(max(alpha, otherRGBA.alpha) - min(alpha, otherRGBA.alpha)) +
       Int(max(red, otherRGBA.red) - min(red, otherRGBA.red)) +
       Int(max(green, otherRGBA.green) - min(green, otherRGBA.green)) +
       Int(max(blue, otherRGBA.green) - min(blue, otherRGBA.blue))
}

That’s a very simple function, but the swift compiler seems to have a threshold for the number of chained operations before the efficiency drops off like a stone.

With a minor rewrite, the compile time went from ~7000ms to 3.5ms to compile the function:

func differenceFrom(otherRGBA: UIImage.RGBA) -> Int {
   let aDiff = Int(max(alpha, otherRGBA.alpha) - min(alpha, otherRGBA.alpha))
   let rDiff = Int(max(red, otherRGBA.red) - min(red, otherRGBA.red))
   let gDiff = Int(max(green, otherRGBA.green) - min(green, otherRGBA.green))
   let bDiff = Int(max(blue, otherRGBA.green) - min(blue, otherRGBA.blue))
   return aDiff + rDiff + gDiff + bDiff
}

For anyone in profiling, this is a good starting point that removes the need to change any settings in Xcode in your project:

xcodebuild -workspace [workspace] -scheme [scheme] clean build OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" | grep .[0-9]ms | grep -v ^0.[0-9]ms | sort -nr > culprits.txt