Swift編譯加速

網上關於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
來源:掘金

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章