swift工程編譯越來(lái)越慢,原來(lái)...

查看編譯時(shí)間
方法1. 在target -> Build Settings-> Other Swift Flags 添加編譯設(shè)置

-Xfrontend -debug-time-function-bodies

查找耗時(shí)代碼

xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build 2>&1 |egrep "\d.\dms"|sort -nr > times.txt

sort -nr會(huì)按照時(shí)間大小排序,當(dāng)編譯完成后,times.txt里可以查看到各個(gè)方法編譯的時(shí)間
然后解決掉前面比較耗時(shí)的代碼 編譯就會(huì)相對(duì)快了

方法2. 不在Build Settings中添加編譯設(shè)置

xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" | egrep "\d.\dms" | egrep -v "\b0.0ms"  > times.txt

此處增加的egrep -v "\b0.0ms"可以排除掉編譯時(shí)間為0.0ms的方法
-workspace yourWorkspaceName.xcworkspace在沒(méi)有workspace 可以省略
-scheme schemeName 沒(méi)有workspace切僅一個(gè)target時(shí)可省略

以下總結(jié)了我自己遇到的幾種比較耗時(shí)的情況: (新建的工程進(jìn)行以下測(cè)試時(shí) 有些不是很明顯,所以在你發(fā)現(xiàn)你的工程編譯越來(lái)越慢時(shí),可以通過(guò)以上的方法 ,來(lái)對(duì)癥下藥)

1.lazy屬性

//
private lazy var label: UILabel = {
    let l = UILabel()
    l.font = UIFont.systemFontOfSize(19)
    return 
}()
//
private lazy var labe1: UILabel = {        
    $0.font = UIFont.systemFontOfSize(19)
    return $0
}(UILabel())
private var label2: UILabel!

self.label2 = UILabel()        
self.label2.font = UIFont.systemFontOfSize(19)

之前在解決編譯慢時(shí) 完全沒(méi)想到 lazy屬性 會(huì)有影響,編譯時(shí)間多大200ms+, 如果僅被編譯一次,那就無(wú)關(guān)痛癢
當(dāng)一個(gè)類使用的地方多的時(shí)候,這個(gè)累會(huì)多次進(jìn)行編譯,假如一個(gè)類在10處有使用,則該類會(huì)被編譯20次??, 200ms * 20 = 4s, 這樣算起來(lái)就... 大家可以自己想象

所以最后筆者把所有的lazy屬性都換掉了 ??

2.數(shù)組操作

 //  321.4ms
 func plus()  {
    let arr1 = ["1"]
    let arr2 = ["2"]
    let arr3 = ["3"]
       
    let result = arr1 + arr2 + arr3
}
// 3.1ms 
func append()  {
      let arr1 = ["1"]
      let arr2 = ["2"]
      let arr3 = ["3"]
        
      var result = arr1
      result.appendContentsOf(arr2)
      result.appendContentsOf(arr3)
}

3.optional

//  2.6ms ?? 與其它操作符一起用 -- 此處可能會(huì)耗時(shí),筆者遇到這里耗時(shí)200ms+的情況,修改了后好了些
var optionalInt: Int? = 10  
let plus = (optionalInt ?? 0) + 10
// 0.5ms 使用變量將?? 的值存起來(lái) 再進(jìn)行預(yù)算
var optionalInt: Int? = 10
var nonnullInt = optionalInt ?? 0    
let plus = nonnullInt + 10
//10.8ms 直接將??運(yùn)算的結(jié)果賦給屬性  可能會(huì)很耗時(shí)!!!
let label = UILabel()
let optionalStr : String? = nil
label.text = optionalStr ?? ""
// 0.3ms ??運(yùn)算的結(jié)果用變量存起來(lái)再賦給屬性
let label = UILabel()
let optionalStr : String? = nil
let displayText = optionalStr ?? ""
label.text = displayText

4.map

//20.3ms
func testLazyMap() {
    let intArr = (0..<100).map{$0}
    let lazyMapResult: [String] = intArr.`lazy`.map{ String($0) }
}
7.5ms
func testDirectMap() {
    let intArr = (0..<100).map{$0}
    let lazyMapResult: [String] = intArr.map{ String($0) }
}

lazy 比非lazy相對(duì)耗時(shí),在編譯慢時(shí)時(shí)間相差會(huì)比較明顯

206.6ms
func test_appendLazyMapArray() {
    let intArr = (0..<100).map{$0}
    
    var result: [String] = []
    result.appendContentsOf(intArr.lazy.map{ String($0) })
}
25.9ms
func test_appendMapArray() {
    let intArr = (0..<100).map{$0}
    var result: [String] = []
    result.appendContentsOf(intArr.map{ String($0) })
}

直接append 帶lazy的數(shù)組和不帶lazy的數(shù)組,不帶lazy的方式編譯快

7.4ms
func test_appendMapedVar() {
    let intArr = (0..<100).map{$0}
    var result: [String] = []
    let maped = intArr.map{ String($0) }
    result.appendContentsOf(maped)
}
33.0ms
func test_appendLazyMappedVar() {
    let intArr = (0..<100).map{$0}
    var result: [String] = []
    let maped = intArr.lazy.map{ String($0) }
    result.appendContentsOf(maped)
}

帶lazy的同樣比無(wú)lazy的慢

5.字符串操作

4.9ms
func plus_asString(){
    let string: NSString = "123"
    let result = "當(dāng)前城市" + (string as String)
}
0.3ms
func plus_stringVAR(){
    let nsstring: NSString = "123"
    let string = nsstring as String
    let result = "當(dāng)前城市" + string
}
17.2ms
func stringFormate(){
    let nsstring: NSString = "123"
    let string = nsstring as String
    let result = "當(dāng)前城市\(zhòng)(string)"
}

這幾種字符串拼接 相差無(wú)幾

6.復(fù)雜一點(diǎn)的集合 eg:字典
這里引入debugging-slow-swift-compile-times的一個(gè)??

//50612.1ms
 [
        "A" : [
            ["B": [1, 2, 3, 4, 5]],
            ["C": [ ]],
            ["D": [ ["A": [ 1 ]]]]
        ]
    ]
// 8.8ms
   [
        "A" : [
            ["B": [1, 2, 3, 4, 5]] as [String: [Int]],
            ["C": [ ]] as [String: [Int]],
            ["D": [ ["A": [ 1 ]] as [String: [Int]]]] as [String : [[String: [Int]]]]
        ]
    ]

在解決掉上面這幾種情況后,工程編譯沒(méi)那么慢了,心情也好多了

參考:
Why is Swift compile time so slow?

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

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

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