Drinking a glass of water, glancing at the Xcode activity view as it was building a project, I saw that until the build completes, I can have another drink. Falling into such mind state came realization of measuring time in number of drinks per compilation… or being smarter than that.
Team leader and the team can eyeball the build times per commit: for one thing to prevent loss of productivity; for another, to discover overhead from dependencies. Build slowness brings many problems in its wake.
The first thing to consider is loss of productivity. Speaking with my colleagues, it is difficult not to get the impression that most software developers expect the compiler to return with feedback fast. Given the fact that with the subsequent builds seconds add up to minutes, is is not surprising that sluggishness can derail focus, thoughts and workflow, touching in particular Continuous Integration and Test Driven Development.
Developers practicing continuous integration merge their changes back to the main branch as often as possible. System validates developer’s changes by creating a build and running automated tests against the build. In similar vein, Test Driven Development, based on running many repeated tests often under one minute, requires building a project before each test.
The second thing to consider is overhead from dependencies. Project growth entails introducing new dependencies and increases building time. Drawing experience from Big O Notation one can assess linear increase as normal, quasi-linear as drawing attention, and exponential as horrible, requiring addressing.
Put bluntly, as tracking build time indicator can protect team morale from suffering, it deserves due attention.
Impelment
Profile
Xcode aids finding code that lags the compiler. In project Build Settings
under Swift-Compiler - Custom Flags
, Other Swift Flags
add:
-Xfrontend -warn-long-expression-type-checking=400
(apple/swift GitHub)-Xfrontend -warn-long-function-bodies=400
(apple/swift GitHub)-Xfrontend -debug-time-function-bodies
The team can adjust the 400
argument with what suits project best. If compiler exceeds the specified millisecond limit, Xcode will raise warning and show the offending place.
- Build Time Analyzer is a macOS app that breaks down Swift build times. Build Time Analyzer for Swift
Improve
- Using explicit types for complex properties saves the time for the compiler and your colleagues to figure out the type.
- Provide types in complex closures.
- Avoid
+
when concatenating strings. - Precompute. Avoid computations directly in the
if-else
conditions. - Dependencies determine what areas of code the system builds. Dependencies within a module are per-file. Dependencies across targets are for the entire target.
- Incremental Builds are file-based. Unrelated changes outside function bodies can result in rebuilding. As changes in function bodies do not affect the file’s interface, modifying function bodies will not recompile other files.
- Limit your Objective-C/Swift interface. Keep your generated header minimal. Use
private
when possible:- Make
IBOutlet private
andIBAction private
. - Make methods exposed to Objective-C
@objc private
. Or switch to block based APIs.
- Make