iOS開發(fā)--優(yōu)化編譯時(shí)間

最近網(wǎng)上閑逛永脓,發(fā)現(xiàn)這篇文章挺好的。翻譯一下 以后備用

1 函數(shù)和表達(dá)式的類型檢查

swift編譯速度緩慢大部分是因?yàn)轭愋蜋z查耗時(shí)長(zhǎng)搅吁。默認(rèn)情況下Xcode不會(huì)顯示編譯慢的代碼落午。你可以通過(guò)指令來(lái)顯示編譯慢的函數(shù)和表達(dá)式,

添加如下指定到build settings -> Other Swift Flag

  • -Xfrontend -warn-long-function-bodies=100 (100這里意思100ms,修改這個(gè)值主要根據(jù)你電腦和項(xiàng)目的速度)
  • -Xfrontend -warn-long-expression-type-checking=100
image

編譯運(yùn)行界拦,可以看到如下結(jié)果

image

下一步就是對(duì)應(yīng)John Sundell
Robert Gummesson 文章 去優(yōu)化編譯器提示的問(wèn)題代碼享甸。

提示:這個(gè)功能在啟動(dòng)模塊優(yōu)化的情況下無(wú)法工作梳侨,所以請(qǐng)關(guān)閉模塊優(yōu)化Whole Module Optimization

??Sources:

編譯緩慢的文件

上面描述如何知道函數(shù)和表達(dá)式的編譯時(shí)間,不過(guò)去知道文件的編譯速度也是很有意思的蚯嫌。
但是 Xcode 沒(méi)有響應(yīng)操作的UI界面割坠,因此你可以可以通過(guò)CLI來(lái)編譯項(xiàng)目

xcodebuild -destination 'platform=iOS Simulator,name=iPhone 8' \
  -sdk iphonesimulator -project YourProject.xcodeproj \
  -scheme YourScheme -configuration Debug \
  clean build \
  OTHER_SWIFT_FLAGS="-driver-time-compilation \
    -Xfrontend -debug-time-function-bodies \
    -Xfrontend -debug-time-compilation" | \
tee profile.log

如果你使用 workspace 請(qǐng)使用-workspace YourProject.xcworkspace 去替換 -project YourProject.xcodeproj
然后使用如下代碼來(lái)提取一些有趣的統(tǒng)計(jì)數(shù)據(jù):

awk '/Driver Compilation Time/,/Total$/ { print }' profile.log | \
  grep compile | \
  cut -c 55- | \
  sed -e 's/^ *//;s/ (.*%)  compile / /;s/ [^ ]*Bridging-Header.h$//' | \
  sed -e "s|$(pwd)/||" | \
  sort -rn | \
  tee slowest.log

你最終得到一個(gè)slowest.log文件妒牙,其中包括項(xiàng)目中的文件以及他們的編譯時(shí)間。類似

2.7288 (  0.3%)  {compile: Account.o <= Account.swift }
2.7221 (  0.3%)  {compile: MessageTag.o <= MessageTag.swift }
2.7089 (  0.3%)  {compile: EdgeShadowLayer.o <= EdgeShadowLayer.swift }
2.4605 (  0.3%)  {compile: SlideInPresentationAnimator.o <= SlideInPresentationAnimator.swift }

提示: 和上面的提示一樣

??Sources:

只構(gòu)建一個(gè)活躍的架構(gòu) (Build active architecture only)

這個(gè)設(shè)置是默認(rèn)的敢朱,不過(guò)你要檢查一下是否設(shè)置正確摩瞎。如下:

image

??Sources:

dSYM生成

默認(rèn)新的項(xiàng)目中拴签,所有的build不會(huì)生成sSYM文件旗们。不過(guò)有時(shí)候當(dāng)我們運(yùn)行在一個(gè)去分析崩潰的而且不能斷點(diǎn)調(diào)試的真機(jī)上,這是相當(dāng)有用的岸梨。(確實(shí) 要點(diǎn)個(gè)贊 這個(gè)tip)
推薦設(shè)置:

image

??Sources:

整個(gè)模塊優(yōu)化

另外一些平常的技巧:

  • 在debug配置中改變Optimization LevelFast, Whole Module Optimization

  • 只在debug配置下為Other Swift Flags添加-Onone標(biāo)記

    image

它指示編譯器器做了如下操作:

  • 一個(gè)模塊里的所有源文件都運(yùn)行在一個(gè)編譯任務(wù)中曹阔,而不是一個(gè)原本件對(duì)應(yīng)一個(gè)編譯任務(wù)。
  • 減少了并行性赃份,但也減少了重復(fù)的工作
  • 這是更快的bug; 但我們需要稍作重復(fù)的工作抓韩。改進(jìn)它是以后的目標(biāo)

注意的是在這設(shè)置下可能有的小改變?cè)隽繕?gòu)建中顯的有點(diǎn)更緩慢。不過(guò)在最壞的情況下你會(huì)看到巨大的提速(項(xiàng)目中有很多2x)

??Sources:

針對(duì)Coco'apod做整個(gè)模塊優(yōu)化

如果你使用Cocoapod渺蒿,你應(yīng)該考慮在你的pod項(xiàng)目沒(méi)有優(yōu)化的情況下啟用WNO,你可以在你的Podfile文件中添加如下post_install鉤子

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      if config.name == 'Debug'
        config.build_settings['OTHER_SWIFT_FLAGS'] = ['$(inherited)', '-Onone']
        config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Owholemodule'
      end
    end
  end
end

然后運(yùn)行pod install. 確保在此更改前后比較構(gòu)建時(shí)間彪薛,以確認(rèn)有改進(jìn)。

三方依賴

這里有2種方式去在你的項(xiàng)目中嵌入三方依賴

  1. 作為那種你每次clean就要重新操作的原件(例如Cocoapod,git submodules,復(fù)制粘貼的代碼少态,app target 依賴的子項(xiàng)目的內(nèi)部庫(kù))
  2. 作為一個(gè)與構(gòu)建的 framework/library(例如 Carthage 易遣,第三方不想提供源代碼發(fā)布的靜態(tài)庫(kù))

CocoaPods 是專為iOS 設(shè)計(jì)最流行的依賴管理,但是導(dǎo)致很長(zhǎng)的編譯時(shí)間侨歉。作為第三方庫(kù)的源代碼揩魂,在大多數(shù)情況下。每次clean都要重新編譯牵舵。通常情況下倦挂,你不需要這樣做。但是實(shí)際上方援,確實(shí)有必要這么做(如 分支切換 Xcode bug)
盡管Carthage非常難用犯戏,但是如果你在乎構(gòu)建時(shí)間的話祖很,這是一個(gè)好的選擇漾脂。僅僅當(dāng)你更改依賴列表時(shí)候(添加刪除依賴,升級(jí)版本)才構(gòu)建外部依賴庫(kù)笨鸡。這需要可能5或者15分鐘坦冠,但是比起嵌入代碼到Cocoapod你要少做很多。
?? Sources:

  • time spent waiting for Xcode to finish builds ??

模塊化

swift的增量編譯并不完美辙浑。有一些項(xiàng)目判呕,我們改變一個(gè)字符串導(dǎo)致整個(gè)增量構(gòu)建過(guò)程中重新編譯。它可以被調(diào)試和改變侠草。但很多好的工具不能被使用边涕。
為了避免這樣的問(wèn)題,你需要將你的項(xiàng)目劃分到不同的模塊中功蜓。在iOS 中動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)都可以(Xcode9 swift支持靜態(tài)庫(kù))
讓我們假如你的項(xiàng)目依賴一個(gè)叫DatabaseKit的內(nèi)部framework。這種方法保證當(dāng)你項(xiàng)目更改一些內(nèi)容重新編譯的時(shí)候童社。DatabaseKit在增量構(gòu)建中不會(huì)重新編譯端衰。

??Sources:

XIBs

xib/sb vs 純代碼 這是一個(gè)非常熱門的話題旅东。不過(guò)我們不會(huì)在這里充分討論十艾。有趣的是,當(dāng)你修改IB中的內(nèi)容忘嫉,這有這個(gè)文件被編譯。另一方面康吵,如果你修改UIView子類的一個(gè)公共方法swift編譯器會(huì)決定重新編譯大部分項(xiàng)目。

??Sources:

Xcode Schemes

通常項(xiàng)目設(shè)置有3個(gè)targets

  • App
  • AppTests
  • AppUITests

在一個(gè)scheme中處理是很好的但是我們可以做的更好同辣。我們最近的設(shè)置是由3個(gè)scheme組成惭载。

APP

使用cmd - b上構(gòu)建應(yīng)用程序的時(shí)候只運(yùn)行單元測(cè)試描滔。用于短迭代,例如在UI代碼中含长,只需要構(gòu)建所需的代碼。

image

App - Unit Test Flow

當(dāng)構(gòu)建app 和 單元測(cè)試的時(shí)候颅眶,只運(yùn)行單元測(cè)試田弥。在編寫單元測(cè)試的時(shí)候非常有用偷厦。因?yàn)楫?dāng)你構(gòu)建單元測(cè)試的時(shí)候能立刻發(fā)現(xiàn)錯(cuò)誤,而不用運(yùn)行他們只泼。

image

App - All Tests Flow

構(gòu)建app 和所有的測(cè)試的時(shí)候请唱。運(yùn)行所有的測(cè)試。UI測(cè)試的時(shí)候非常有用聚至。

image

??Sources:

使用新的Xcode構(gòu)建系統(tǒng)

Xcode9 蘋果介紹了一種新的構(gòu)建系統(tǒng)本橙。目前是預(yù)覽版,默認(rèn)不使用贷币。這筆默認(rèn)構(gòu)建系統(tǒng)明顯更快。在Xcode文件菜單中選擇Workspace or Project Settings 去可以切換都新的構(gòu)建系統(tǒng)偶摔。

??Sources:

顯示Xcode的編譯時(shí)間

最后促脉,為了讓我們知道我們的構(gòu)建系統(tǒng)是否提升了。我們需要在Xcode界面上顯示構(gòu)建時(shí)間亡呵。運(yùn)行如下命令顯示:

$ defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES

一旦我們這樣做了硫戈。cmd b我們可以看見(jiàn)

image

我推薦比較相同條件下的構(gòu)建時(shí)間
1 退出Xcode
2 清除派生的數(shù)據(jù)
3 在Xcode項(xiàng)目中打開你的項(xiàng)目
4 在Xcode打開或索引階段完成后立即開始構(gòu)建。第一個(gè)方法似乎更具有代表性汁胆,因?yàn)閺腦code 9構(gòu)建開始也執(zhí)行了索引霜幼。
可選擇的,你可以在命令行下運(yùn)行

$ time xcodebuild other params

??Sources:


原文鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铸题,一起剝皮案震驚了整個(gè)濱河市丢间,隨后出現(xiàn)的幾起案子驹针,更是在濱河造成了極大的恐慌,老刑警劉巖柬甥,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苛蒲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡撤防,警方通過(guò)查閱死者的電腦和手機(jī)寄月,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)厂抖,“玉大人克懊,你說(shuō)我怎么就攤上這事∏蕉” “怎么了扮念?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巧勤。 經(jīng)常有香客問(wèn)我弄匕,道長(zhǎng),這世上最難降的妖魔是什么剩瓶? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任城丧,我火速辦了婚禮,結(jié)果婚禮上搂鲫,老公的妹妹穿的比我還像新娘磺平。我一直安慰自己,他們只是感情好擦酌,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布菠劝。 她就那樣靜靜地躺著,像睡著了一般笼平。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锌唾,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天夺英,我揣著相機(jī)與錄音,去河邊找鬼余黎。 笑死载萌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炒考。 我是一名探鬼主播斋枢,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼描姚!你這毒婦竟也來(lái)了戈次?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绊寻,失蹤者是張志新(化名)和其女友劉穎悬秉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體村缸,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡武氓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了东羹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡渊额,死狀恐怖垒拢,靈堂內(nèi)的尸體忽然破棺而出火惊,到底是詐尸還是另有隱情,我是刑警寧澤屹耐,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布惶岭,位于F島的核電站,受9級(jí)特大地震影響按灶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜噪矛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一铺罢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缩滨,春花似錦泉瞻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)巧娱。三九已至烘贴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間老翘,已是汗流浹背锻离。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卫键,地道東北人虱朵。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像絮宁,于是被迫代替她去往敵國(guó)和親服协。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容