在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>源碼下載>通訊/手機編程>

怎樣提高iOS工程打包的速度

大小:0.3 MB 人氣: 2017-09-25 需要積分:1

過慢的編譯速度有非常明顯的副作用。一方面,程序員在等待打包的過程中可能會分心,比如刷刷朋友圈,看條新聞等等。這種認知上下文的切換會帶來很多隱形的時間浪費。另一方面,大部分 app 都有自己的持續集成工具,如果打包速度太慢, 會影響整個團隊的開發進度。

因此,本文會分別討論日常開發和持續集成這兩種場景,分析打包速度慢的瓶頸所在,以及對應的解決方案。利用這些方案,筆者成功的把公司 app 的持續集成時間從 45 min 成功的減少到 9 min,效率提升高達 80%,理論上打包速度可以提升 10 倍以上。如果用一句話總結就是:

在絕對的實力(硬件)面前,一切技巧(軟件)都是浮云

日常開發

其實日常開發的優化空間并不大,因為默認情況下 Xcode 會使用上次編譯時留下的緩存,也就是所謂的增量編譯。因此,日常開發的主要耗時由三部分構成:

總耗時 = 增量編譯 + 鏈接 + 生成調試信息(dSYM)

這里的增量編譯耗時比較短,即使是在我 14 年高配的 MacBook Pro(4核心,8 線程,2.5GHz i7 4870HQ,下文簡稱 MBP) 上,也僅僅耗時十秒上下。我們的應用代碼量大約一百多萬行,業內超過這個量級的應用應該不多。鏈接和生成調試信息各花費不到 20s,因此一次增量的編譯的時間開銷在半分鐘到一分鐘左右,我們逐個分析:

增量編譯: 因為耗時較短(大概十幾秒或者更少),幾乎不存在優化的空間,但是非常容易惡化。因為只有頭文件不變的編譯單元才能被緩存,如果某個文件被 N 個文件引用,且這個文件的頭文件發生了變化,那么這 N 個文件都會重編譯。APP 的分層架構一般都會做,但一個典型的誤區是在基礎庫的頭文件中使用宏定義,比如定義一些全局都可以讀取的常量,比如是否開啟調試,服務器的地址等等。這些常量一旦改變(比如為了調試或者切換到某些分支)就會導致應用重編譯。

鏈接:鏈接沒有緩存,而且只能用單核進行,因此它的耗時主要取決于單核性能和磁盤讀寫速度。考慮到我們的目標文件一般都比較小,因此 4K 隨機讀寫的性能應該會更重要一些。

調試信息:日常開發時,并不需要生成 dSYM 文件,這個文件主要用于崩潰時查找調用棧,方便線上應用進行調試,而開發過程中的崩潰可以直接在 Xcode 中看到,關閉這個功能 不會對開發產生任何負面影響。

日常開發的優化空間不大,即使是龐大的項目,落后的機器性能,關閉 dSYM 以后也就耗時 30s 左右。相比之下,打包速度可以優化和討論的地方就比較多了。

持續集成

在利用 Jenkins 等工具進行持續集成時,緩存不推薦被使用。這是因為蘋果的緩存不夠穩定,在某些情況下還存在 bug。比如明明本地已經修復了 bug,可以編譯通過,但上次的編譯緩存沒有被正確清理,導致在打包機器上依然無法編譯通過。或者本地明明寫出了 bug,但同樣由于緩存問題,打包機器依然可以編譯通過。

因此,無論是手動刪除 Derived Data 文件夾,還是調用 xcodebuild clean 命令,都會把緩存清空。或者直接使用 xcodebuild archive,會自動忽略緩存。每次都要全部重編譯是導致打包速度慢的根本原因。以我們的項目為例,總計 45min 的打包時間中,有 40min 都在執行 xcodebuild 這一行命令。

使用 CCache 緩存

最自然的想法就是使用緩存了,既然蘋果的緩存不靠譜,那么就找一個靠譜的緩存,比如 CCache。它是基于編譯器層面的緩存,根據目前反饋的情況看,并不存在緩存不一致的問題。根據筆者的實驗,使用 CCache 確實能夠較大幅度的提升打包速度,刪除緩存并使用 CCache 重編譯后,耗時只有十幾分鐘。

然而,CCache 最致命的問題是不支持 PCH 文件和 Clang modules。PCH 的本意是優化編譯時間,我們假設有一個頭文件 A 依賴了 M 個頭文件,其中每個被依賴的頭文件又依賴了 N 個 頭文件,如下圖所示:

怎樣提高iOS工程打包的速度

由于 #import 的本質就是把被依賴頭文件的內容拷貝到自己的頭文件中來,因此頭文件 A 中實際上包含了 M * N 個頭文件的內容,也就需要 M * N 次文件 IO 和相關處理。當項目中每增加一個依賴頭文件 A 的文件,就會重復一次上述的 M * N 復雜度的過程。

PCH 文件的好處是,這個文件中的頭文件只會被編譯一次并緩存下來,然后添加到項目中 所有 的頭文件中去。上述問題倒是解決了,但很智障的一點是,所有文件都會隱式的依賴所有 PCH 中的文件,而真正需要被全局依賴的文件其實非常少。因此實際開發中,更多的人會把 PCH 當成一種快速 import 的手段,而非編譯性能的優化。前文解釋過,PCH 文件一旦發生修改,會導致徹徹底底,完完整整的項目重編譯,從而降低編譯速度。正是因為 PCH 的副作用甚至抵消了它帶來的優化,蘋果已經默認不使用 PCH 文件了。

用來取代 PCH 的就是 Clang modules 技術,對于開啟了這一選項的項目,我們可以用@import 來替代過去的 #import,比如:

@import UIKit;

等價于

#import 《UIKit/UIKit.h》

拋開自動鏈接 framework 這些小特性不談,Clang modules 可以理解為模塊化的 PCH,它具備了 PCH 可以緩存頭文件的優點,同時提供了更細粒度的引用。

說回到 CCache,由于它不支持 PCH 和 Clang modules,導致無法在我們的項目中應用。即使可以用,也會拖累項目的技術升級,以這種代價來換取緩存,只怕是得不償失。

distcc

distcc 是一種分布式編譯工具,可以把需要被編譯的文件發送到其他機器上編譯,然后接收編譯產物。然而,經過貼吧、貝聊、手Q 等應用的多方實驗,發現并不適合 iOS 應用。它的原理是多個客戶端共同編譯,但是絕大多數文件其實編譯時間非常短,并不值得通過網絡來回傳送,這種方案應該只適合單個文件體量非常大的項目。在我們的項目中,使用 distcc大幅度增加了打包時間,大約耗時 1 小時左右。

定位瓶頸

在尋求外部工具無果后,筆者開始嘗試著對編譯時間直接做優化。為了搞清楚這 40min 究竟是如何花費的,我首先對 xcodebuild 的輸出結果進行詳細分析。

使用過 xcodebuild 命令的人都會知道,它的輸出結果對開發者并不友好,幾乎沒有可讀性,好在還有 xcpretty 這個工具可以格式化它:

gem install xcpretty

通過 gem 安裝后,只要把 xcodebuild 的輸出結果通過管道傳給 xcpretty 即可:

xcodebuild -scheme Release 。。. | xcpretty

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      主站蜘蛛池模板: 午夜精品福利在线 | 成人剧场 | 操的好爽 | 天天狠天天透天干天天怕处 | 午夜视频1000 | 日日搞夜夜操 | 国产午夜精品久久久久免费视小说 | 日夜操在线视频 | 人人玩人人弄人人曰 | 91大神精品全国在线观看 | www.色黄 | 免费大片黄国产在线观看 | 四虎影院新地址 | 456主播喷水在线观看 | 四虎影院永久在线 | 免费国产成人午夜私人影视 | 天天做天天爱天天爽 | 国产成人乱码一区二区三区 | 国产一级做a爱免费观看 | 视频在线精品 | 热99re久久精品2久久久 | 毛片黄| 干一干操一操 | 日本久久综合视频 | 中文字幕在线看视频一区二区三区 | 天天色天天操综合网 | 色色色爱 | 正在播放91大神调教偷偷 | 国产丝袜va丝袜老师 | 人人干人人艹 | 网友自拍区一区二区三区 | 丁香在线| 四虎影院久久 | 色综合久久久久久久久久久 | 中文字幕va一区二区三区 | 免费看吻胸亲嘴激烈网站 | 亚州人成网在线播放 | 青青热久久国产久精品秒播 | 欧美特黄视频在线观看 | 婷婷 夜夜| 国产内地激情精品毛片在线一 |