swift工程编译越来越慢,原来...

查看编译时间
方法1. 在target -> Build Settings-> Other Swift Flags 添加编译设置

-Xfrontend -debug-time-function-bodies

查找耗时代码

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

sort -nr会按照时间大小排序,当编译完成后,times.txt里可以查看到各个方法编译的时间
然后解决掉前面比较耗时的代码 编译就会相对快了

方法2. 不在Build Settings中添加编译设置

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"可以排除掉编译时间为0.0ms的方法
-workspace yourWorkspaceName.xcworkspace在没有workspace 可以省略
-scheme schemeName 没有workspace切仅一个target时可省略

以下总结了我自己遇到的几种比较耗时的情况: (新建的工程进行以下测试时 有些不是很明显,所以在你发现你的工程编译越来越慢时,可以通过以上的方法 ,来对症下药)

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)

之前在解决编译慢时 完全没想到 lazy属性 会有影响,编译时间多大200ms+, 如果仅被编译一次,那就无关痛痒
当一个类使用的地方多的时候,这个累会多次进行编译,假如一个类在10处有使用,则该类会被编译20次😱, 200ms * 20 = 4s, 这样算起来就... 大家可以自己想象

所以最后笔者把所有的lazy属性都换掉了 😄

2.数组操作

 //  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 ?? 与其它操作符一起用 -- 此处可能会耗时,笔者遇到这里耗时200ms+的情况,修改了后好了些
var optionalInt: Int? = 10  
let plus = (optionalInt ?? 0) + 10
// 0.5ms 使用变量将?? 的值存起来 再进行预算
var optionalInt: Int? = 10
var nonnullInt = optionalInt ?? 0    
let plus = nonnullInt + 10
//10.8ms 直接将??运算的结果赋给属性  可能会很耗时!!!
let label = UILabel()
let optionalStr : String? = nil
label.text = optionalStr ?? ""
// 0.3ms ??运算的结果用变量存起来再赋给属性
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相对耗时,在编译慢时时间相差会比较明显

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的数组和不带lazy的数组,不带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的同样比无lazy的慢

5.字符串操作

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

这几种字符串拼接 相差无几

6.复杂一点的集合 eg:字典
这里引入debugging-slow-swift-compile-times的一个🌰

//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]]]]
        ]
    ]

在解决掉上面这几种情况后,工程编译没那么慢了,心情也好多了

参考:
Why is Swift compile time so slow?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容