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

sjlzz1221 5年前
   <p>查看编译时间</p>    <p><strong>方法1. 在 target -> Build Settings -> Other Swift Flags 添加编译设置</strong></p>    <pre>  <code class="language-swift">-Xfrontend -debug-time-function-bodies</code></pre>    <p>查找耗时代码</p>    <pre>  <code class="language-swift">xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build 2>&1 |egrep "\d.\dms"|sort -nr > times.txt</code></pre>    <p>sort -nr 会按照时间大小排序,当编译完成后,times.txt里可以查看到各个方法编译的时间</p>    <p>然后解决掉前面比较耗时的代码 编译就会相对快了</p>    <p><strong>方法2. 不在Build Settings中添加编译设置</strong></p>    <pre>  <code class="language-swift">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</code></pre>    <p>此处增加的 egrep -v "\b0.0ms" 可以排除掉编译时间为0.0ms的方法</p>    <p>-workspace yourWorkspaceName.xcworkspace 在没有workspace 可以省略</p>    <p>-scheme schemeName 没有workspace切仅一个target时可省略</p>    <p>以下总结了我自己遇到的几种比较耗时的情况: (新建的工程进行以下测试时 有些不是很明显,所以在你发现你的工程编译越来越慢时,可以通过以上的方法 ,来对症下药)</p>    <h3><strong>1.lazy属性</strong></h3>    <pre>  <code class="language-swift">//  private lazy var label: UILabel = {      let l = UILabel()      l.font = UIFont.systemFontOfSize(19)      return   }()</code></pre>    <pre>  <code class="language-swift">//  private lazy var labe1: UILabel = {              $0.font = UIFont.systemFontOfSize(19)      return $0  }(UILabel())</code></pre>    <pre>  <code class="language-swift">private var label2: UILabel!    self.label2 = UILabel()          self.label2.font = UIFont.systemFontOfSize(19)</code></pre>    <p>之前在解决编译慢时 完全没想到 lazy属性 会有影响,编译时间多大200ms+, 如果仅被编译一次,那就无关痛痒</p>    <p>当一个类使用的地方多的时候,这个累会多次进行编译,假如一个类在10处有使用,则该类会被编译20次:scream:, 200ms * 20 = 4s, 这样算起来就... 大家可以自己想象</p>    <p>所以最后笔者把所有的lazy属性都换掉了 :smile:</p>    <h3><strong>2.数组操作</strong></h3>    <pre>  <code class="language-swift">//  321.4ms   func plus()  {      let arr1 = ["1"]      let arr2 = ["2"]      let arr3 = ["3"]        let result = arr1 + arr2 + arr3  }</code></pre>    <pre>  <code class="language-swift">// 3.1ms   func append()  {        let arr1 = ["1"]        let arr2 = ["2"]        let arr3 = ["3"]          var result = arr1        result.appendContentsOf(arr2)        result.appendContentsOf(arr3)  }</code></pre>    <h3><strong>3.optional</strong></h3>    <pre>  <code class="language-swift">//  2.6ms ?? 与其它操作符一起用 -- 此处可能会耗时,笔者遇到这里耗时200ms+的情况,修改了后好了些  var optionalInt: Int? = 10    let plus = (optionalInt ?? 0) + 10</code></pre>    <pre>  <code class="language-swift">// 0.5ms 使用变量将?? 的值存起来 再进行预算  var optionalInt: Int? = 10  var nonnullInt = optionalInt ?? 0      let plus = nonnullInt + 10</code></pre>    <pre>  <code class="language-swift">//10.8ms 直接将??运算的结果赋给属性  可能会很耗时!!!  let label = UILabel()  let optionalStr : String? = nil  label.text = optionalStr ?? ""</code></pre>    <pre>  <code class="language-swift">// 0.3ms ??运算的结果用变量存起来再赋给属性  let label = UILabel()  let optionalStr : String? = nil  let displayText = optionalStr ?? ""  label.text = displayText</code></pre>    <h3><strong>4.map</strong></h3>    <pre>  <code class="language-swift">//20.3ms  func testLazyMap() {      let intArr = (0..<100).map{$0}      let lazyMapResult: [String] = intArr.`lazy`.map{ String($0) }  }</code></pre>    <pre>  <code class="language-swift">7.5ms  func testDirectMap() {      let intArr = (0..<100).map{$0}      let lazyMapResult: [String] = intArr.map{ String($0) }  }</code></pre>    <p>lazy 比非lazy相对耗时,在编译慢时时间相差会比较明显</p>    <pre>  <code class="language-swift">206.6ms  func test_appendLazyMapArray() {      let intArr = (0..<100).map{$0}        var result: [String] = []      result.appendContentsOf(intArr.lazy.map{ String($0) })  }</code></pre>    <pre>  <code class="language-swift">25.9ms  func test_appendMapArray() {      let intArr = (0..<100).map{$0}      var result: [String] = []      result.appendContentsOf(intArr.map{ String($0) })  }</code></pre>    <p>直接append 带lazy的数组和不带lazy的数组,不带lazy的方式编译快</p>    <pre>  <code class="language-swift">7.4ms  func test_appendMapedVar() {      let intArr = (0..<100).map{$0}      var result: [String] = []      let maped = intArr.map{ String($0) }      result.appendContentsOf(maped)  }</code></pre>    <pre>  <code class="language-swift">33.0ms  func test_appendLazyMappedVar() {      let intArr = (0..<100).map{$0}      var result: [String] = []      let maped = intArr.lazy.map{ String($0) }      result.appendContentsOf(maped)  }</code></pre>    <p>带lazy的同样比无lazy的慢</p>    <h3><strong>5.字符串操作</strong></h3>    <pre>  <code class="language-swift">4.9ms  func plus_asString(){      let string: NSString = "123"      let result = "当前城市" + (string as String)  }</code></pre>    <pre>  <code class="language-swift">0.3ms  func plus_stringVAR(){      let nsstring: NSString = "123"      let string = nsstring as String      let result = "当前城市" + string  }</code></pre>    <pre>  <code class="language-swift">17.2ms  func stringFormate(){      let nsstring: NSString = "123"      let string = nsstring as String      let result = "当前城市\(string)"  }</code></pre>    <p>这几种字符串拼接 相差无几</p>    <h3><strong>6.复杂一点的集合 eg:字典</strong></h3>    <p>这里引入 debugging-slow-swift-compile-times 的一个:chestnut:</p>    <pre>  <code class="language-swift">//50612.1ms   [          "A" : [              ["B": [1, 2, 3, 4, 5]],              ["C": [ ]],              ["D": [ ["A": [ 1 ]]]]          ]      ]</code></pre>    <pre>  <code class="language-swift">// 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]]]]          ]      ]</code></pre>    <p>在解决掉上面这几种情况后,工程编译没那么慢了,心情也好多了</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/71bbc843abdb</p>    <p> </p>