本文共 4772 字,大约阅读时间需要 15 分钟。
随着 Xcode8
和 swift3.0
的正式到来,我开始着手将 swift2.3
的项目转到 swift3
(至于转换过程,这里不多做介绍,Xcode自带的转换工具,基本可以转换80%左右,剩下的自己慢慢调试即可。)但是,转到swift3只会,在用Xcode8编译,发现编译过程变得非常慢,哪怕打一个空格,都要重新编译很久。于是在网上查找解决办法,查找了半天各种方法全用,发现于事无补。
有什么加一个 HEADERMAP_USES_VFS = YES
()
通过多次编译查看,发现在Xcode左边栏,最后一个选项,是每次的编译运行等记录, 每行记录中都会有每次编译的文件编译记录。如下图
再次查看正在编译的一条记录(正在编译的记录后面有一个转圈圈的”菊花“),发现有图中1、2两种标识, 一个绿色:white_check_mark:说明,这是编译完成了,另一个是灰色→箭头,说明是正在编译;此时发现灰色一直停留在这里,指向图中的文件,左边的菊花一直转个不停, 编译卡住了。这样一来就找到编译是什么文件导致的那么慢。
排查的方法,采用比较笨的方法,暴力注释方法: 就是注释找到卡住的文件中的所有方法里的代码,不要注释方法,再次编译,此时发现该文件很快通过编译,然后在依次解开部分方法注释,再次编译,直到发现解开某个方法的注释后,编译再次卡住,那就说明那个方法中的代码写的有问题,然后在依次注释,解开注释,排查方法中的某一行代码的问题。 经过一番排查,我找到了我代码中卡住的部分代码,如下图红色圈中的代码
在字典中的key对应的value,没有给直接的值,而是给出一个表达式,这样会导致Xcode8的编译速度极其慢,不知道为什么会出现这样的问题,之前的Xcode版本是没有的。
找到问题所在,解决问题就简单了,于是修改代码如下图:
修改之后,再次编译,重新回到了快速编译的时代了,再也不用等上5-10分钟不等了。
以上过程,是针对我遇到的问题而言的,不知道是否存在普遍性,如若你也遇到,刚好看了我的文章,也解决了问题,那就会心一笑吧,如若你也遇到了,但是没有解决问题,也请你会心一笑吧。
有时候自己慢慢去探索出问题的所在,也是很不错的体验。
XCode默认使用与CPU核数相同的线程来进行编译,但由于编译过程中的IO操作往往比CPU运算要多,因此适当的提升线程数可以在一定程度上加快编译速度。 2. 将Debug Information Format改为DWARF 在工程对应Target的Build Settings中,找到Debug Information Format这一项,将Debug时的DWARF with dSYM file改为DWARF。 这一项设置的是是否将调试信息加入到可执行文件中,改为DWARF后,如果程序崩溃,将无法输出崩溃位置对应的函数堆栈,但由于Debug模式下可以在XCode中查看调试信息,所以改为DWARF影响并不大。这一项更改完之后,可
一,非代码层面的检查和优化
Swift作为一个新兴的语言,有着苹果Dad(dy???)的支持与良好的社区环境。于是乎大家都开始慢慢尝试在项目中使用Swift。在我们的项目中就有大量的Swift,但是过慢的编译时间真的是killing us。 完整的编译一次可能需要15到20分钟,完全不能忍。
先说结果,在我的电脑MacPro上,项目编译时间直接从以前20m41s
缩短了10m16s
。
而这10分钟仅仅只是从的代码层面带来的效果
国外友人Robert已经为我们写好了一个Swift编译时间定位的工具【】。 方便好用,可以立竿见影的找到问题代码。
ps:以前也用XCTOOL但是xocde8已经不再支持build了,非常可惜。
原码:
var model : UILabel?var cat : String?var name : String?var number : Int?//build tiem : 8740.3msfunc sendData() { let parameter = ["model" : model?.text ?? "", "cat" : cat ?? "", "name" : name ?? "", "number" : number ?? 0, "dog" : "dog"] print("send request with parameter:\(parameter)")}
这段代码所需要的编译时间是8740.3ms
,就这么一个字典定义,我们竟然浪费了8秒!
指定类型之后我们再来看看
//build time: 3235.4mslet parameter : [String : AnyObject] = ["model" : model?.text ?? "", "cat" : cat ?? "", "name" : name ?? "", "number" : number ?? 0, "dog" : "dog"]
这次所需要的编译时间就已经缩短为了3235.4ms
,通过手动指定类型,我们缩短了5s
以上的时间让费
再紧接,我们继续观察,这个parameter的字典其实可以全部为String,根本用不到AnyObject。
指定特定的类型
//build time: 200.3mslet parameter : [String : String] = ["model" : model?.text ?? "", "cat" : cat ?? "", "name" : name ?? "", "number" : "\(number ?? 0)", "dog" : "dog"]
这次所需要的编译时间就已经缩短为了200.3ms
,把AnyObject ->String ,我们缩短了2s
以上的时间让费!!
所以如果你可以一种类型搞定,请千万别写AnyObject
!!!
通过指定正确的类型我们从8740ms
的编译时间缩短到了200ms
!!!!
nil
保护抽离//build time : 9804msfunc calculateSize(view : UIView?) -> CGSize{ return CGSize(width: 10 + (view?.bounds.width ?? 0) + (view?.bounds.height ?? 0) + 22, height: 20)}//build time : 172msfunc calculateSize(view : UIView?) -> CGSize{ let width = view?.bounds.width ?? 0 let height = view?.bounds.height ?? 0 return CGSize(width: 10 + width + height + 22, height: 20)}
这段代码编译了9804ms
,只是因为我们在运算的时候一并加入nil的保护。如果我们拆离nil保护,编译时间缩短了98.3%
- 使用三目运算(Bool ? a : b)时也非常耗时,但还没有到非常严重的程度,一个三目可能需要额外的
100ms
到200ms
编译时间- 当你在字典中使用nil保护时,也可能造成极长的编译时间,有时候甚至会长达
20s
.但不是每次都出现。我理项目时就通过发现了很多这样的问题。比如:["model" : model?.text ?? ""]
. 在通过把他们强制转化成想要的类型String
后得到解决:["model" : (model?.text ?? "")as String]
。 暂时还不知道为什么。 猜测是因为model?.text
的text属性是一个可选型, compiler花费了很长的时间来确定到底是Optional(String)
还是String
.但又不是每次都出现,非常奇怪。
+
、+=
运算符//build time 1400.6msfunc arrPlusOperatos() { let arr1 = [1,2,3] let arr2 = [3,4,5] result += arr1 + arr2 + [10]}//build time 8.6msfunc arrPlusOperatos() { let arr1 = [1,2,3] let arr2 = [3,4,5] result.appendContentsOf(arr1) result.appendContentsOf(arr2) result.appendContentsOf([10])}
尽量少的使用+
、+=
号来合并参数, 在项目中有一些array的合并编译时间高达5000ms
.
对于
String
也是一样的,String
使用\(value)
来合并值,或API给的append.
上面的几个问题是在整理项目(Swift2.3)中,特别明显影响编译速度的点:
具体大家可以用来查看项目哪些func
存在严重的编译过长问题。
更多:
框架上的提高编译性能:
其他一些Xcode优化包括: