前言
Swift編譯時(shí)間過(guò)長(zhǎng)碴卧,是件難以忍受的事情。你能忍心看著幾行看似簡(jiǎn)單的代碼抖格,慢吞吞的編譯嗎诺苹?╮(╯_╰)╭。下面來(lái)介紹幾種減少編譯時(shí)間的方法雹拄。
查看每個(gè)函數(shù)編譯時(shí)間
若要對(duì)癥下藥收奔,首先要抓住作祟的小鬼。有2種方法滓玖。
1坪哄、在build setting中,設(shè)置Other Swift Flags為-Xfrontend -debug-time-function-bodies势篡。這樣編譯時(shí)清楚的看到每個(gè)函數(shù)的編譯時(shí)間翩肌,找到耗時(shí)較多的地方。
點(diǎn)擊右邊的展開(kāi)按鈕禁悠,可詳細(xì)查看時(shí)間摧阅。
2、Xcode plugin绷蹲,https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode
方法
明確指明類(lèi)型棒卷,不要讓編譯器去推斷
經(jīng)過(guò)測(cè)試,發(fā)現(xiàn)祝钢,在ViewDidLoad中添加如下代碼比规,build的話,在我的機(jī)器上一直卡著不動(dòng)拦英。原因不明蜒什,不知道是機(jī)器還是xcode問(wèn)題,還是本身就很慢疤估。但是在原文章說(shuō)灾常,耗時(shí)630ms×迥矗總之看起來(lái)是比較耗時(shí)的钞瀑。
let myCompany = [
"employees": [
"employee 1": ["attribute": "value"],
"employee 2": ["attribute": "value"],
"employee 3": ["attribute": "value"],
"employee 4": ["attribute": "value"],
"employee 5": ["attribute": "value"],
"employee 6": ["attribute": "value"],
"employee 7": ["attribute": "value"],
"employee 8": ["attribute": "value"],
"employee 9": ["attribute": "value"],
"employee 10": ["attribute": "value"],
"employee 11": ["attribute": "value"],
"employee 12": ["attribute": "value"],
"employee 13": ["attribute": "value"],
"employee 14": ["attribute": "value"],
"employee 15": ["attribute": "value"],
"employee 16": ["attribute": "value"],
"employee 17": ["attribute": "value"],
"employee 18": ["attribute": "value"],
"employee 19": ["attribute": "value"],
"employee 20": ["attribute": "value"],
]
]
但是將類(lèi)型聲明之后,
let myCompany: Dictionary<String, AnyObject> = ...
ViewDidLoad消耗的時(shí)間立馬降到十幾ms慷荔。
nil判斷
將nil判斷寫(xiě)成if let方式解包雕什。
class CMExpandingTextField: UITextField {
func textFieldEditingChanged() {
invalidateIntrinsicContentSize()
}
override func intrinsicContentSize() -> CGSize {
if isFirstResponder(), let text = text {
let size = text.sizeWithAttributes(typingAttributes)
// Build time: 5238.3ms
return CGSize(width: size.width + (rightView?.bounds.width ?? 0) + (leftView?.bounds.width ?? 0) + 22, height: bounds.height)
// Build time: 32.4ms
var padding: CGFloat = 22
if let rightView = rightView {
padding += rightView.bounds.width
}
if let leftView = leftView {
padding += leftView.bounds.width
}
return CGSizeMake(size.width + padding, bounds.height)
}
return super.intrinsicContentSize()
}
}
array+[]
將array+[data],變成array.append(data)
// Build time: 1250.3ms
let systemOptions = [ 7, 14, 30, -1 ]
let systemNames = (0...2).map{ String(format: localizedFormat, systemOptions[$0]) } + [NSLocalizedString("everything", comment: "")]
// Some code in-between
labelNames = Array(systemNames[0..<count]) + [systemNames.last!]
// Build time: 25.5ms
let systemOptions = [ 7, 14, 30, -1 ]
var systemNames = systemOptions.dropLast().map{ String(format: localizedFormat, $0) }
systemNames.append(NSLocalizedString("everything", comment: ""))
// Some code in-between
labelNames = Array(systemNames[0..<count])
labelNames.append(systemNames.last!)
三段式判斷 a > b ? a : b
// Build time: 239.0ms
let labelNames = type == 0 ? (1...5).map{type0ToString($0)} : (0...2).map{type1ToString($0)}
// Build time: 16.9ms
var labelNames: [String]
if type == 0 {
labelNames = (1...5).map{type0ToString($0)}
} else {
labelNames = (0...2).map{type1ToString($0)}
}
CGFloat-->CGFloat類(lèi)型轉(zhuǎn)換
// Build time: 3431.7 ms
return CGFloat(M_PI) * (CGFloat((hour + hourDelta + CGFloat(minute + minuteDelta) / 60) * 5) - 15) * unit / 180
// Build time: 3.0ms
return CGFloat(M_PI) * ((hour + hourDelta + (minute + minuteDelta) / 60) * 5 - 15) * unit / 180
Round()
// Build time: 1433.7ms
let expansion = a — b — c + round(d * 0.66) + e
// Build time: 34.7ms
let expansion = a — b — c + d * 0.66 + e
總結(jié)
減少編譯時(shí)間歸結(jié)于幾點(diǎn):
1、明確指明類(lèi)型贷岸,而不要讓編譯器去推斷代碼中你所使用的類(lèi)型壹士,這樣會(huì)節(jié)省大部分的時(shí)間。
2偿警、減少讓編譯器懵逼的代碼躏救,盡量寫(xiě)的簡(jiǎn)單,明了螟蒸,不要繞圈子盒使。
Whether or not you have a problem with slow build times, it is still useful to build an understanding of what confuses the compiler. I’m sure you’ll find a few surprises yourself
一句話,要善意的對(duì)待編譯器尿庐,不要整各種來(lái)虐待它~ o( ̄▽?zhuān)?/em>)ブ~