Swift Optimization

I learned a hard lesson today: to make Swift really fast you have to know what you’re doing. You can’t just slap some code together and expect it to be zippy without understanding some of how Swift was designed and how it works. There is a very good presentation by some of the team members that built Swift here. My initial takeaway was that it was important to finalize any classes you didn’t plan on subclassing, incrementally check the timing analyzer, and finally, employ whole module optimization.

Structs > Classes

If you can get away with replacing classes with structs, then use structs. You may be able to build just enough functionality without incurring the extra baggage of classes and reference counting.

final

Using the final modifier on a class, function, or variable reduces the number of steps of indirection and lookup the compiler must interject at runtime. When classes and functions lack the final modifier, the compiler can’t be sure that there aren’t subclasses, or overridden methods lurking around that need to be accessed instead. Using the final modifier on a class applies finality to all of its methods and attributes. Since structs cannot be subclassed anyway, they are already optimized and do not need a final modifier.

Use the Time Profiler

Using the time profiler incrementally as you code can help you spot bottlenecks earlier, and avoid headaches down the road. I’ve found that it’s easier to understand the stack trace and find bottlenecks when Whole Module Optimization is turned off.

Whole Module Optimization

The key insight here is that XCode compiles files in parallel, and only when they’ve changed, thus reducing compilation time in development. The downside is that when the compiler is compiling files separately, it misses optimizations that may pop up across multiple files. By enabling Whole Module Optimization you will incur a longer compile time, but you may drastically improve the speed of your final product.