preface

In the process of Swift project, with the increasing number of code, the compilation speed of each debugging is getting slower and slower. It even takes more than 6 minutes to compile the project under debug. Then began to study how to shorten the compilation time.

How do I get the exact compile time?

Before compiling, perform the following two steps:

  1. Empty all files in the Derived Data folder (a cleanup tool is recommendedCleaner for Xcode, can be found in the Mac App Store.)
  2. inXcodeClean (CMD + Shift +k)
  3. The ability to have Xcode show compilation time, terminal input
/ / Xcode shows the build time set up / / in the terminal input defaults write com. Apple. Dt. Xcode ShowBuildOperationDuration YESCopy the code

Xcode configuration optimization

// 1 Build Settings -> Swift Compiler - Code Generation -> Optimization Level Debug change to None Add SWIFT_WHOLE_MODULE_OPTIMIZATION = YES to user-defined Debug. For other Release configurations, use NO // 3 Build Settings -> Build Options -> DEBUG_INFORMATION_FORMAT Debug to DWARF // 4 Build Settings -> Architectures -> Build Active Architecture Only Debug to YESCopy the code

The following links explain the difference between SWIFT_WHOLE_MODULE_OPTIMIZATION and Optimization Level. In short, the former is optimized for all code at the global level, while the latter is optimized for each file. What is the difference between User Defined SWIFT_WHOLE_MODULE_OPTIMIZATION and Swift Optimization Level?

Code optimization

For optimization at the code level, we can rely on Xcode to find out time-consuming methods for targeted optimization.

configuration

Xcode -> Build Settings -> Swift complier-custom Flags Debug Add // 1 method body length exceeds 100 ms-xfrontend -warn-long-function-bodies=100 // 2 When the type conclusion duration exceeds 100 ms-xfrontend -warn-long-expression-type-checking=100Copy the code

After adding the above configuration, Xcode will display warning whenever it takes more than 100 ms. The duration here can be adjusted according to the actual situation.

Xcode layer modification

Code level modification

For the code that generated the warning, we can make the following changes.

1 specifies the variable type

Common variables

/ / modify before
var name = getName()
/ / modified
var name: String = getName()
Copy the code

An array of

/ / modify before
let array = ["a"."b"."c"."d"."e"."f"."g"]
/ / modified
let array: [String] = ["a"."b"."c"."d"."e"."f"."g"]
Copy the code

closure

/ / modify before
let sum = [1.2.3].map { String($0) }.flatMap { Int($0)}.reduce(0, +)
/ / modified
let sum = [1.2.3].map { (num: Int) - >String in String(num) }.flatMap { (str: String) - >Int? in Int(str) }.reduce(0, +)
Copy the code

2 Split chain Closure

/ / modify before
let sum = [1.2.3].map { String($0) }.flatMap { Int($0)}.reduce(0, +)
/ / modified
let numbers = [1.2.3]
let stringNumbers = numbers.map { String($0)}let intNumbers = stringNumbers.flatMap { Int($0)}let sum = intNumbers.reduce(0, +)
Copy the code

3 avoid null conjunction operators??

You can use if let instead

/ / modify before
let name = string ?? ""
/ / modified
if let name = string{ 
 /* string has value */
}else{
 /* string is nil*/
}
Copy the code

4 Avoid ternary operators?

/ / modify before
let letter = isFirst ? "a" : "b"
/ / modified
var letter = ""
if isFirst { 
  letter = "a"
} else {
  letter = "b"
}
Copy the code

Do not use + to concatenate strings and arrays

string

/ / modify before
let url = "https://google.com/" + "path/" + "anotherpath"
/ / modified
let url = "https://google.com/\("path")/\("anotherpath")"
Copy the code

An array of

/ / modify before
let systemNames = (0.2).map{ String(format: localizedFormat, systemOptions[$0} + [])NSLocalizedString("everything", comment: "")]
/ / modified
var systemNames = systemOptions.dropLast().map{ String(format: localizedFormat, $0) }
systemNames.append(NSLocalizedString("everything", comment: ""))
Copy the code

Avoid doing too much arithmetic in if else if

/ / modify before
if number == 60 * 60 {}
/ / modified
let number: Double = 60 * 60
if number == 3600{}Copy the code

Avoid meaningless type conversions

// If variable a is already of type CGFloat, do not force CGFloat(a)

/ / modify before
return CGFloat(M_PI) * (CGFloat((hour + hourDelta + CGFloat(minute + minuteDelta) / 60) * 5) - 15) * unit / 180

/ / modified
return CGFloat(M_PI) * ((hour + hourDelta + (minute + minuteDelta) / 60) * 5 - 15) * unit / 180

Copy the code

8 Use Let Private Final

Use Final analysis

9 Use custom operators (especially with generic parameters)

The results of

Finally, through optimization at Xcode and code levels, the compilation time was reduced from about 360 s to 190 s. Wow!

Other compile time analysis tools

BuildTimeAnalyzer-for-Xcode

Refer to the link

  1. Sundell Improving Swift compile times
  2. Improve your Xcode (Swift) Compile Time
  3. Optimizing Compilation Time for Swift Code
  4. How to make Swift compile faster
  5. Speed up Swift compile time
  6. Regarding Swift build time optimizations
  7. Swift build time optimizations — Part 2