Image for post
Image for post

Swift build time optimizations — Part 2

Robert Gummesson
Jun 29, 2016 · 3 min read

It’s soon been two months since I wrote the first post on this topic. That post introduced the Build Time Analyzer for Xcode which was written to help identifying areas where the Swift compiler struggled.

The plug-in has since then spread throughout the Swift community and during the WWDC labs, lots of people were seen using it. Consequently, something quite interesting happened. Apple reached out to me and made an enhancement request (see the new Occurrences column).

There are two types of causes for slow build times that can be identified with the plug-in. The first is where an individual routine takes too long to compile. This was the focus of my previous post and I listed a few examples and workarounds there. The other is where closures and lazy properties are getting type checked far too many times. This will be the focus of this post.

Closures and lazy properties

I recently added a new column to the plug-in window called Occurrences. The purpose is to make it easier to understand why relatively simple code sometimes slows down the build process.

Image for post
Image for post

As seen above, a couple of lazy getters are occurring 159 times in my Xcode build log. In fact, I can open up any file in the log and see a reference to it. Below are some examples taken from 3 separate files, none of which references CMGridView in the code.

So it turns out that the compiler is type checking my lazy property for every single .swift file in the target, adding up to a cumulative build time of 1905.5ms (using Swift 2.2). For Swift 3.0, the issue persists but the build time is nearly cut in half.

If you are using lazy properties in your projects, I really recommend paying attention to this. Before refactoring my code in the above example, I used to have quite a few more of these.

Let’s have a look at the code.

…and if you think 2 seconds is bad for compiling that, it gets even worse if a closure is used.

Image for post
Image for post

The code:

Workaround

To improve the build time for these, simply move out the code to private methods wherever possible.

The lazy property above will still receive repeated type checking but with the code moved out, the build time is now reduced by 96.7%.

Build times in Swift 3.0 so far

With Xcode 8.0, the era of Xcode plug-ins ended and a new era of Xcode extensions begun. Given the limitations of extensions, I am working on making the plug-in a standalone app. It will (hopefully) be out well before Xcode 8.0 comes out of beta. In the meantime, here are some comparisons based on the examples listed in my previous post.

Ternary operator

Nil Coalescing Operator

ArrayOfStuff + [Stuff]

Performance surprises in Swift 3.0

While the above looks promising, I did notice several new issues in Swift 3.0. But to be fair, Xcode 8 is still in beta and I didn’t benchmark the overall build time. Time will tell if I need to write a third post on this topic… 😉

The Swift Programming Language

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store