網上關於Swift編譯加速的文章挺多,這裏就不贅述。 這裏推薦全方位無死角講編譯優化的文檔Optimizing-Swift-Build-Times
還有優化的神器BuildTimeAnalyzer-for-Xcode
下面就針對於具體代碼層面的編譯優化
談一些心得和感悟。
如何找出項目中編譯耗時的代碼?
在XCode 10的時候Swift就支持了監控的編譯超時的警告。 它能幫助我們找到項目中需要編譯優化的函數,並量化具體的優化時間。
在Build Settings ➔ Swift Compiler - Custom Flags ➔ Other Swift Flags
中添加.
/// <limit>爲warning的編譯時間閾值
-Xfrontend -warn-long-function-bodies=<limit>
-Xfrontend -warn-long-expression-type-checking=<limit>
複製代碼
作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!
測試機型: A12z Apple DTK(所以編譯時間會看起來短很多)
Let's Start
tip1: 使用 + 拼接可選字符串會極其耗時。
建議:改寫成 "(string1)(string2)"的形式
耗時代碼:編譯耗時372ms
let finalResult = (dbWordModel?.vocabularyModel?.justSentenceExplain ?? "") + "<br/>" + (dbWordModel?.vocabularyModel?.justSentence ?? "")
複製代碼
優化後: 編譯時間20ms 18.5倍
的編譯性能提升🤯。
let finalResult = "\(dbWordModel?.vocabularyModel?.justSentenceExplain ?? "")<br/>\(dbWordModel?.vocabularyModel?.justSentence ?? "")"
複製代碼
Tip2: 可選值使用??
賦默認值再嵌套其他運算會極其耗時。
優化方法: 使用guard let 解包。
還是上面的例子 優化後: 編譯耗時 63ms 5.9倍的編譯性能提升。
guard let dbSentenceExp = dbWordModel?.vocabularyModel?.justSentenceExplain,
let dbSentence = dbWordModel?.vocabularyModel?.justSentence else { return }
let finalResult = "\(dbSentenceExp)<br/>\(dbSentence)"
複製代碼
Tip3: 將長計算式代碼拆分 最後組合計算。
耗時代碼:編譯時長736ms
let totalTime = (timeArray.first?.float()?.int ?? 0) * 60 + (timeArray.last?.float()?.int ?? 0)
複製代碼
優化拆分後: 耗時22ms 33.4倍
編譯性能提升🤯
let firstPart: Int = (timeArray.first?.float()?.int ?? 0)
let lastPart: Int = (timeArray.last?.float()?.int ?? 0)
let totalTime = firstPart * 60 + lastPart
複製代碼
Tip4: 與或非和>=,<=,==邏輯運算嵌套Optional會比較耗時。
建議: 使用guard let + 拆分 進行優化。
耗時代碼: 10420ms 編譯器已經無法編譯並報錯。
if (homeMainVC?.scrollview.contentOffset.y ?? 0) >= ((homeMainVC?.headHeight ?? 0) - (homeMainVC?.ignoreTopSpeace ?? 0)) {
}
複製代碼
優化後: 21ms 496倍
編譯性能提升🤯
let leftValue: CGFloat = homeMainVC?.scrollview.contentOffset.y ?? 0
let rightValue: CGFloat = (homeMainVC?.headHeight ?? 0.0) - (homeMainVC?.ignoreTopSpeace ?? 0.0)
if leftValue == rightValue {
}
複製代碼
Tip5: 手動增加類型推斷會降低編譯時間。
在Tip4的基礎上我們二次優化:優化前:21ms
let leftValue = homeMainVC?.scrollview.contentOffset.y ?? 0
let rightValue = (homeMainVC?.headHeight ?? 0.0) - (homeMainVC?.ignoreTopSpeace ?? 0.0)
複製代碼
優化後:增加了類型推斷 16ms
let leftValue: CGFloat = homeMainVC?.scrollview.contentOffset.y ?? 0
let rightValue: CGFloat = (homeMainVC?.headHeight ?? 0.0) - (homeMainVC?.ignoreTopSpeace ?? 0.0)
複製代碼
結論:
項目中的一百多個編譯優化之後性能在MacBook pro 15寸 16款 i7 上面(重啓電腦clear Xcode 立即編譯的情況下)
編譯速度從262s
提升到了228s
, 提升了34s
, 在公司性能較差的打包機上提升可能會更快。
感悟:
有的時候在編譯性能
和代碼的可閱讀性
之間需要有一個權衡取捨。
一昧的追求編譯性能而捨棄代碼的可閱讀性不可取。
電腦性能比較差的情況下浪費大部分時間在編譯上也不可取。
M1芯片的電腦另說🐶。
附錄: Measuring Swift compile times in Xcode 9
作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!
作者:liaoWorkin
鏈接:https://juejin.cn/post/6898893810319753224
來源:掘金