swift工程编译越来越慢,原来...
sjlzz1221
8年前
<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>