美文网首页IOS三人行swift开发Swift知识集
swift工程编译越来越慢,原来...

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

作者: 冰琳92 | 来源:发表于2016-10-08 17:31 被阅读2522次

查看编译时间
方法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?

相关文章

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

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

  • Swift 工程速度编译慢

    在Xcode 7.2上编译Swift编译速度越来越慢,查了很多资料下面是我总结的几点原因。下面代码均为Swift ...

  • 在远程Ubuntu上编译Android工程

    最近Android工程越来越大了,AndroidStudio编译起来越来越慢,编译的时候就电脑卡死,当然更换电脑应...

  • Swift 编译时间折半优化

    前言 在 Swift 项目过程中,随着代码量的不断增加,每次调试的编译速度越来越慢,在 debug 下编译项目竟然...

  • 查看Xcode编译时间

    最近工程因为代码增多, 编译越来越慢, 为了更快编译, 找出了下面的方法,通过查看各部分代码的编译时间消耗长短,针...

  • 查看Xcode编译时间

    最近工程因为代码增多, 编译越来越慢, 为了更快编译, 找出了下面的方法,通过查看各部分代码的编译时间消耗长短,针...

  • iOS中关于宏定义与常量的使用

    现在在做的这个产品,由于需求不断的添加,工程越来越大,编译速度是越来越慢。之前就看过帖子: 使用宏定义过多的话,随...

  • Android组件化方案

    组件化 随着项目功能的增多,单一工程项目下的代码越来越多,编译速度越来越慢。无论采用最初的MVC,还是改进化的MV...

  • 将iOS项目进行子工程化

    在iOS项目开发中,随着项目的越来越大,工程的结构化会变差,编译的速度也会越来越慢。使用静态库或动态库的方式来构建...

  • Showing All Messages Undefined s

    oc工程中使用swift的第三方库framework源码,结果oc工程中没有一个swift文件,导致编译报错。 解...

网友评论

  • _小单:times.txt 没有任何内容是怎么回事?
    _小单:@冰琳92 喔,可是编译器提示编译成功了呀, 第二种方式也不行,编译不了。
    冰琳92:编译失败了~
  • 程序员钙片吃多了:这些总结点,很多都把代码改的不好看或者说冗余,作者提出的这些观点有没有从根本去分析原因?没有原因分析,可能有点无法接收把代码改的冗提升余。而且,编译耗时严重主要可能还是混编引起的。苹果说Xcode9混编提升40%的效率。
    冰琳92:@程序员钙片吃多了 大部分的tip都是以主动写明对应的类型,相对编译时间也少了,可以猜测是这些情况下,XCode 类型推断不成功,导致会编译很久,如果是类型推断的问题,也没法查明原因,只能期待苹果改善这个问题了
    程序员钙片吃多了:@冰琳92 了解,不过我问题的关键是...这些tips为何能够如此高效的改善编译速度,最好能从编译过程来分析,这样才更能说服采用ugly的代码来换取编译速度的提升
    冰琳92:@程序员钙片吃多了 是纯Swift测试的:relieved:
  • 左手边是幸福:这个命令xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build 2>&1 |egrep "\d.\dms"|sort -nr > times.txt是在终端编译的吗,最后生成的time.tex哪里可以看到我这个编译会报 does not exist.
    冰琳92:先在XCode里看下能否编译通过,如果可以,就能在工程文件目录同级找到time.txt文件的
  • PisPMPL:<invalid loc> 获取不到对应的代码位置。
    冰琳92:@perfectisshittt 这个对应某个property 如果时间没有排序的话 在这个get上面 应该是可以看到对应的属性名字的
    PisPMPL:@冰琳92 生成的time.text

    0.8ms <invalid loc> get {}

    这是里面的一段获取不到对应的代码位置
    冰琳92:@perfectisshittt 可以把问题说得详细点
  • MarkLin:```
    xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build 2>&1 |egrep "\d.\dms"|sort -nr > times.txt

    ```

    无法编译。。
    MarkLin:@冰琳92 好吧。是我的问题,其实已经编译了,只是在命令行没有输出,我以为编译不了。
    冰琳92:@MarkLin 没用过任何插件哈 上面只用到了两个东西 xcodebuild和egrep,xcodebuild是苹果自己提供的,安装了xcode就有啦,egrep估计是系统自有的,因为我没安装过
    如果编译不了 先用XCode看下是不是工程编译不过
    MarkLin:@MarkLin 楼主命令是用的插件 DVTPlugInCompatibilityUUIDs 实现的吧。。难怪我在 xcode8 上编译不了

本文标题:swift工程编译越来越慢,原来...

本文链接:https://www.haomeiwen.com/subject/hylfyttx.html