Swift 推斷速度優(yōu)化總結(jié)

Swift編譯速度(推斷速度)優(yōu)化總結(jié)

測試基于2018款MacBook pro(主頻2.6的i7), Xcode 11.3, Swift 5.1.3

測試時(shí)在 OTHER_SWIFT_FLAGS 里加入:

-Xfrontend
-warn-long-expression-type-checking=100

還有一個(gè)推斷方法時(shí)間的Flag我沒用, 那個(gè)加上去到處都是超時(shí), 根本改不完...

實(shí)際上改100個(gè)超過100ms的也僅僅快了10秒, 改1000個(gè)以上才能明顯感覺到變快...只能說日常開發(fā)注意了

  1. 不要嵌套閉包
    Swift推斷閉包(方法)需要把內(nèi)部所有代碼都推斷完才能推斷出閉包的類型, 這時(shí)候推斷效率會變得奇低, 速度最低時(shí)只有正常情況下的1/10, 如:
fileprivate lazy var bindPhoneCell: AccountBindButton = {
    let cell = AccountBindButton()
    cell.rx.controlEvent(.touchUpInside).subscribe { [weak self] (_) in
        ...
    }.disposed(by: disposeBag)
    return cell
}()
  1. 類型屬性的初始化不能過于復(fù)雜, 大概是閉包里超過7行, 類似于:
class contactView: UIView {
    private lazy var wechatContact: VerticalAlignButton = {
        let button = VerticalAlignButton(type: .custom)
        button.innerSpace = 12
        button.corner(byRoundingCorners: .allCorners, radius: 8.adp.cgFloat)
        button.layer.masksToBounds = true
        button.imageEdgeInsets = UIEdgeInsets(top: 6, left: 0, bottom: 0, right: 0)
        button.setImage(UIImage(named: "icon_wechat_about"), for: .normal)
        button.setImage(UIImage(named: "icon_wechat_about"), for: .selected)
        button.setTitleColor(UIColor.Global.messageTextColor, for: .normal)
        button.titleLabel?.font = UIFont.Global.fontDFYuanGBW5(with: 16)
        button.backgroundColor = UIColor.Global.whiteBGColor
        return button
    }()
}
  1. 屬性能不用閉包盡量不要用閉包(帶閉包的)初始化, 比如2里面那種, 或者類似于:
private lazy var wechatContact = VerticalAlignButton(type: .custom).config {
    $0.innerSpace = 12
}

但寫起來是真的快樂, 快樂就完事了

  1. 閉包的類型寫不寫完整區(qū)別不大, 編譯器為了驗(yàn)證類型是否正確總是會自己推斷一遍的

  2. 有返回值的閉包比無返回值的閉包需要更長的推斷時(shí)間(大概1.5到2倍), 所以上述2里的例子改寫成3里的例子會快一些, 但除非閉包非常復(fù)雜否則差別不大

  3. 重載的函數(shù)會增加3到10倍的推斷時(shí)間, 比如:

Int(floor(progress * 100)) 和 (progress * 100).floor.int

點(diǎn)名批評一下Snapkit和RxSwift這兩個(gè)用了大量重載函數(shù)的庫, 超過100ms的代碼一半都是這兩個(gè)庫的閉包方法, 還有WCDB.swift的where語句也難以推斷, 簡單的像:

Properties.userId == 0 && Properties.resourceId == 1 && Properties.chapterId == 2

就得推斷140ms, 服了

  1. 短表達(dá)式的推斷速度:
    只讀屬性 > 調(diào)用protocol方法快 > 作為泛型參數(shù)傳進(jìn)方法/重載的函數(shù)
    比如:
1.double(單獨(dú)寫的double屬性) > 1.double(BinaryInteger的extension) > Double(1)

慢的時(shí)候(嵌套太多的時(shí)候)速度可能會相差上百倍

  1. 使用Codable的類型創(chuàng)建太多靜態(tài)屬性也會導(dǎo)致推斷時(shí)間變長:
struct Para: Codable {
    ...
}

extension Para {
    static let network: Para(...)//這種靜態(tài)屬性一多就會出現(xiàn)推斷超時(shí)
}
  1. 在閉包里使用DEBUG宏也會導(dǎo)致推斷時(shí)間增加, 非常的迷

  2. if/guard 里用,代替&&會提高推斷速度, 看情況用,的時(shí)候編譯器會把if后面的東西當(dāng)成遞進(jìn)的關(guān)系, 而用&&的時(shí)候是平行的關(guān)系

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容