有效提升Swift編譯速度

Swift/Xcode編譯慢, 加快編譯速度, Swift/Xcode Long Compile time
作者:yuan

- iOS
- Swift
- Xcode

前言


Swift作為一個新興的語言,有著蘋果Dad(dy???)的支持與良好的社區環境。于是乎大家都開始慢慢嘗試在項目中使用Swift。在我們的項目中就有大量的Swift,但是過慢的編譯時間真的是killing us。 完整的編譯一次可能需要15到20分鐘,完全不能忍。

先說結果,在我的電腦MacPro上,項目編譯時間直接從以前20m41s縮短了10m16s
而這10分鐘僅僅只是從的代碼層面帶來的效果

定位問題


國外友人Robert已經為我們寫好了一個Swift編譯時間定位的工具【請戳這里】。 方便好用,可以立竿見影的找到問題代碼。

ps:以前也用XCTOOL但是xocde8已經不再支持build了,非常可惜。

代碼優化


指定類型與拒絕泛型

原碼:

var model : UILabel?
var cat : String?
var name : String?
var number : Int?
//build tiem : 8740.3ms
func sendData() {
    let parameter = ["model" : model?.text ?? "",
                     "cat" : cat ?? "",
                     "name" : name ?? "",
                     "number" : number ?? 0,
                     "dog" : "dog"]
    print("send request with parameter:\(parameter)")
}

這段代碼所需要的編譯時間是8740.3ms,就這么一個字典定義,我們竟然浪費了8秒!

指定類型之后我們再來看看

//build time: 3235.4ms
let parameter : [String : AnyObject] = ["model" : model?.text ?? "",
                               "cat" : cat ?? "",
                               "name" : name ?? "",
                               "number" : number ?? 0,
                               "dog" : "dog"]

這次所需要的編譯時間就已經縮短為了3235.4ms,通過手動指定類型,我們縮短了5s以上的時間讓費

再緊接,我們繼續觀察,這個parameter的字典其實可以全部為String,根本用不到AnyObject。

指定特定的類型

//build time: 200.3ms
let parameter : [String : String] = ["model" : model?.text ?? "",
                    "cat" : cat ?? "",
                    "name" : name ?? "",
                    "number" : "\(number ?? 0)",
                    "dog" : "dog"]

這次所需要的編譯時間就已經縮短為了200.3ms,把AnyObject ->String ,我們縮短了2s以上的時間讓費!!

所以如果你可以一種類型搞定,請千萬別寫AnyObject!!!

通過指定正確的類型我們從8740ms的編譯時間縮短到了200ms!!!!

運算時nil保護抽離

//build time : 9804ms
func calculateSize(view : UIView?) -> CGSize{
    return CGSize(width: 10 + (view?.bounds.width ?? 0) + (view?.bounds.height ?? 0) + 22, height: 20)
}

//build time : 172ms
func calculateSize(view : UIView?) -> CGSize{
    let width = view?.bounds.width ?? 0
    let height = view?.bounds.height ?? 0
    return CGSize(width: 10 + width + height + 22, height: 20)
}

這段代碼編譯了9804ms,只是因為我們在運算的時候一并加入nil的保護。如果我們拆離nil保護,編譯時間縮短了98.3%

  • 使用三目運算(Bool ? a : b)時也非常耗時,但還沒有到非常嚴重的程度,一個三目可能需要額外的 100ms200ms編譯時間
  • 當你在字典中使用nil保護時,也可能造成極長的編譯時間,有時候甚至會長達20s.但不是每次都出現。我理項目時就通過BuildTimeAnalyzer發現了很多這樣的問題。比如:["model" : model?.text ?? ""]. 在通過把他們強制轉化成想要的類型String后得到解決:["model" : (model?.text ?? "")as String]。 暫時還不知道為什么。 猜測是因為 model?.text 的text屬性是一個可選型, compiler花費了很長的時間來確定到底是Optional(String)還是String.但又不是每次都出現,非常奇怪。

少用++=運算符

//build time 1400.6ms
func arrPlusOperatos() {
    let arr1 = [1,2,3]
    let arr2 = [3,4,5]
    result += arr1 + arr2 + [10]
}
//build time 8.6ms
func arrPlusOperatos() {
    let arr1 = [1,2,3]
    let arr2 = [3,4,5]
    result.appendContentsOf(arr1)
    result.appendContentsOf(arr2)
    result.appendContentsOf([10])
}

盡量少的使用++=號來合并參數, 在項目中有一些array的合并編譯時間高達5000ms.

對于String也是一樣的,String 使用\(value)來合并值,或API給的append.

總結


上面的幾個問題是在整理項目(Swift2.3)中,特別明顯影響編譯速度的點:

  • 指定類型、拒絕泛型
  • 運算時nil保護抽離、少用三目運算
  • 少用+、+=運算符
    縮短了我們接近50%的Swift編譯時間。

具體大家可以用BuildTimeAnalyzer來查看項目哪些func存在嚴重的編譯過長問題。

更多:

  1. regarding-swift-build-time-optimizations
  2. swift-compiler-performance-tips-and-tricks
  3. why-is-swift-compile-time-so-slow

后續


框架上的提高編譯性能:

  • 模塊化代碼,使用私有Cocoapods repository. 讓不同模塊以Framework或則.a文件的形式在項目里使用。如此每次編譯的時候就只需要編譯自己模塊下的代碼。其他模塊的代碼將會被編譯后緩存,不需要重復編譯。

其他一些Xcode優化包括:

  • Find Implicit Dependencies Off [1]
  • Build Active Architecture Only Yes On Debug [2]
  • Precompile Prefix Header set to YES [3]
  • defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 4 [4]
  • RAM Disk [5]沒有嘗試過,有機會可以試一下
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 關于 Swift 重要這個文檔所包含的準備信息, 是關于開發的 API 和技術的。這個信息可能會改變, 根據這個文...
    無灃閱讀 4,378評論 1 27
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,245評論 4 61
  • 其實你只需要擔心一件事,你配不上自己的野心,也辜負了自己所受的苦難,每天都會經歷各種各樣的困難,但是卻沒有迎難而上!
    不羨仙2閱讀 144評論 0 0
  • 在微信公眾號上做作文批改評點指導,作文升格指導到今天剛好5個月,也在國省市許多刊物上發表了不少作文指導和輔導文章(...
    朱老師語文工作室閱讀 439評論 0 1
  • 昨天晚上沒睡好一直很困就懶在家一直不想出門磨蹭到2點半才到店里媽媽有點不高興弄得我也不高興為什么要把自己的負面情緒...
    無可緊要的小事情閱讀 95評論 0 0