在 Swift 項目過程當中,隨着代碼量的不斷增長,每次調試的編譯速度愈來愈慢,在 debug 下編譯項目居然須要 6 min 以上。遂開始研究如何縮短編譯時長。git
編譯前,請執行如下兩個步驟:github
Cleaner for Xcode
,能夠在 Mac App Store 搜索下載到)Xcode
中 clean(快捷鍵:cmd+shift+k)// Xcode 顯示構建時長設置
// 在 terminal 中輸入
defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES
複製代碼
// 1
Build Settings -> Swift Compiler - Code Generation -> Optimization Level 下 Debug 修改成 None
// 2
Build Settings -> User-Defined 下 Debug 增長 SWIFT_WHOLE_MODULE_OPTIMIZATION = YES,其它諸如 Release 配置請使用 NO
// 3
Build Settings -> Build Options -> DEBUG_INFORMATION_FORMAT 下 Debug 修改成 DWARF
// 4
Build Settings -> Architectures -> Build Active Architecture Only 下 Debug 改成 YES
複製代碼
關於 SWIFT_WHOLE_MODULE_OPTIMIZATION
和 Optimization Level
的區別,如下連接有詳細說明。簡單來講前者是從全局層面對全部代碼進行優化,然後者是針對每一個 file 的優化。 What is the difference between User Defined SWIFT_WHOLE_MODULE_OPTIMIZATION and Swift Optimization Level?express
代碼層面的優化,咱們能夠依靠 Xcode 找出耗時較長的方法,進行鍼對性優化。swift
Xcode -> Build Settings -> Swift Complier - Custom Flags
Debug 下增長
// 1 方法體時長超過 100 ms
-Xfrontend -warn-long-function-bodies=100
// 2 類型推斷時長超過 100 ms
-Xfrontend -warn-long-expression-type-checking=100
複製代碼
添加如上配置之後,只要時長超出100 ms,Xcode 中便會顯示 warning。這裏的時長能夠根據實際狀況進行調整。數組
針對產生 warning 的代碼處,咱們就能夠根據下面進行鍼對性修改啦。xcode
普通變量bash
// 修改前
var name = getName()
// 修改後
var name: String = getName()
複製代碼
數組閉包
// 修改前
let array = ["a", "b", "c", "d", "e", "f", "g"]
// 修改後
let array: [String] = ["a", "b", "c", "d", "e", "f", "g"]
複製代碼
閉包app
// 修改前
let sum = [1, 2, 3].map { String($0) }.flatMap { Int($0) }.reduce(0, +)
// 修改後
let sum = [1, 2, 3].map { (num: Int) -> String in String(num) }.flatMap { (str: String) -> Int? in Int(str) }.reduce(0, +)
複製代碼
// 修改前
let sum = [1, 2, 3].map { String($0) }.flatMap { Int($0) }.reduce(0, +)
// 修改後
let numbers = [1, 2, 3]
let stringNumbers = numbers.map { String($0) }
let intNumbers = stringNumbers.flatMap { Int($0) }
let sum = intNumbers.reduce(0, +)
複製代碼
可使用 if let 來代替less
// 修改前
let name = string ?? ""
// 修改後
if let name = string{
/* string has value */
}else{
/* string is nil*/
}
複製代碼
// 修改前
let letter = isFirst ? "a" : "b"
// 修改後
var letter = ""
if isFirst {
letter = "a"
} else {
letter = "b"
}
複製代碼
字符串
// 修改前
let url = "https://google.com/" + "path/" + "anotherpath"
// 修改後
let url = "https://google.com/\("path")/\("anotherpath")"
複製代碼
數組
// 修改前
let systemNames = (0...2).map{ String(format: localizedFormat, systemOptions[$0]) } + [NSLocalizedString("everything", comment: "")]
// 修改後
var systemNames = systemOptions.dropLast().map{ String(format: localizedFormat, $0) }
systemNames.append(NSLocalizedString("everything", comment: ""))
複製代碼
// 修改前
if number == 60 * 60 {}
// 修改後
let number: Double = 60 * 60
if number == 3600 {
}
複製代碼
// 好比變量 a 已是 CGFloat 類型,不要再強轉 CGFloat(a)
// 修改前
return CGFloat(M_PI) * (CGFloat((hour + hourDelta + CGFloat(minute + minuteDelta) / 60) * 5) - 15) * unit / 180
// 修改後
return CGFloat(M_PI) * ((hour + hourDelta + (minute + minuteDelta) / 60) * 5 - 15) * unit / 180
複製代碼
最終經過 Xcode 和代碼兩個層面的優化,編譯時間從原先的 360 s 左右縮減到 190 s。哇哦!