编译优化
引言
随着模块和代码量的增加,编译的效率会越来越低,有的多达几个小时,这时候需要考虑做编译优化:
1.查找耗时文件和代码
2.针对性文件和代码做优化(代码简化,减少宏定义,库二进制化等)
3.项目结构组件化和模块化,拆分功能减少编译量(这个属于组件化的范畴,这里忽略)
查找和排序
这里需要脚本处理来获取编译数据日志 :
1 |
|
查找耗时文件和代码
原理
将编译日志按行有序输出到allFilesTimeCompile.txt文件中,然后根据每行输出时间的间隔长短进行排序,将时间长的靠前10000行输出到timeCompileSorted.txt文件中。
解释
- xcodebuild是编译命令,这里”xcodebuild -workspace projectName.xcworkspace -scheme targetName -archivePath
/Desktop/targetName archive”表示编译打包的archive文件路径在”/Desktop/targetName.archive”。 - xcpretty是美化编译日志的,表示按行输出日志。
- gnomon是标记出另外一个命令执行消耗的时间信息,这里用于每个文件编译的时间信息统计。
- sort排序命令行,这里使用管道输出将allFilesTimeCompile.txt文件的前10000行写入timeCompileSorted.txt文件中。
使用
将上面的脚本放入一个.sh文件中(里面的projectName和targetName替换成自己的项目名和target名,archive的路径也可以按照自己的需求来),然后将该.sh文件放入项目根目录下,在通过控制台进入该项目根目录执行该.sh文件等待即可。
优化策略
代码简化
顾名思义就是进行代码冗余简化,重复代码进行合并或者是将冗余逻辑进行优化精简代码量,原理就是减少编译器的编译代码数量,从表层上降低编译器的编译时间。
减少宏定义
主要是将大量的宏定义更改为静态全局变量,这样将本身的预编译时间
延后到了运行期
,这样以来达到精简编译时间的目的,当然这种方式优化有限,不过精益求精总是好的。
库的二进制化
我们在项目中会大量使用一些第三方库或者自定义的私有库,这时候如果引入的是源码,当然会需要编译器的编译处理,部分第三方库在编译器里会占用大量编译时间。
疑问一:二进制化指什么意思?
简单来说就是打包成framework或者.a文件,即是静态库,(动态库是Apple禁止的,但是iOS10以上放开限制,允许使用动态库进行主从app的共用)因为静态库里面已经是编译好的二进制码,所以编译时会直接跳过,这样就减少了编译时间。
疑问二:二进制化后如果有依赖是否也在里面?要是其他静态库也包含了同样的依赖会不会编译冲突?
如果打包的是.a静态库,那么依赖肯定是在里面的,如果其他静态库也用到了同样的依赖,编译器会报重复编译冲突错误。所以一般都是不建议打包.a静态库的,除非本身不包含其他的依赖库。
解决方案:打包成不包含依赖的framework静态库。
二进制化方案
网上有很多方案,大体分为三种:
- 脚本,这种最常见,网上例子,可以去搜寻下,这里不多说了;
- Aggregate文件,这种方案与上面那种类似,不过是单独用一个Aggregate独立出来了,路径
File——>New——>Target——>Cross-platform——>Aggregate
,然后在Aggregate的target选中Build Phases——>+ New Run Script Phase——>shell
加入脚本。执行脚本的流程即可; - 使用Cocoapods的package命令行,package命令需要先通过命令行安装cocoapods-packager,在库项目的根目录下执行
pod package xxx.podspec --force
,当然这里有个注意事项,存在图片资源等bundle的需要从framework中单独提出来,放在framework中与代码文件夹并列的位置,否则库本身的资源文件无法读取出来。这里介绍的package方案比较全面,可以研究下关于使用CocoaPods的package打包Framework以及使用注意。
- 本文作者:习武
- 本文链接:https://xiwuxisheng.github.io/2019/06/26/iOS/%E7%BC%96%E8%AF%91%E4%BC%98%E5%8C%96/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!