Swift 项目编译优化(一)

级别:★☆☆☆☆
标签:「编译过程」「Swift 项目优化编译时间」
做者: WYW
审校: QiShare团队php


前言
前段时间笔者组内同事十分快速地开发了一个应用(不妨设应用名为QiShareDemo),笔者在使用8+128的Mac Air 运行项目的时候,发现项目编译时间比较久,查看了相关资料,并作了部分实践,落地了这篇文章。 笔者在 clone 了 QiShareDemo 后,发现全量编译编译项目的编译时间为105.207s; 后来通过笔者的部分优化编译时间处理后,全量编译项目的时间缩短为44.573s; 固然这里还能够继续作优化,能够根据项目中具体的代码的编译耗时排序,处理那些编译耗时较长的代码。html

1、名词简介

下边笔者对本文中提到的名词作一个简单介绍。前端

1. 全量编译

以Xcode编译过程为例,笔者理解的全量编译的一种状况为:把Xcode 编译项目时生成的Derived Data 删除后,再次编译项目的过程。git

2. 增量编译

以Xcode编译过程为例,笔者理解的增量编译的一种状况为:Xcode 已编译过项目的状况下,咱们又修改了部分文件,那么编译的时候,就会编译咱们修改过的文件,及引用过相关文件的文件。github

3. Swift Compiler

若是项目不是 Objective-C 和 Swift 混编的项目而是纯 Swift 项目,那么编译过程用的是 Swift Compiler,笔者在下文中第三部分的2.1.2部分有提到详情。关于编译的更多详情能够查看 浅谈编译过程express

2、Swift 项目的编译过程

使用 Xcode 查看项目具体编译过程的方式以下:swift

1. 用 Xcode 查看项目具体编译过程

用 Xcode 查看项目编译过程方式:command + b 编译项目,在 Xcode 中,按下图方式查看具体编译过程。微信

compileProcess1

笔者根据 Xcode 编译项目过程,作了以下 Swift 项目编译过程示意图。markdown

SwiftCompileProcess.png

2. 查看项目编译时间

咱们的目的是要优化项目的编译时间,那么首先咱们应该知道当前编译时间。 查看项目编译时间的方式为:在终端中输入以下命令:defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES 以后在 Xcode 顶部的 切换Scheme和运行设备的那一栏中便可看到具体编译时间。 查看具体编译时间方式以下图所示:架构

Xcode compile Time

上图是查看项目整体编译时间的方式,那么咱们想要对项目作编译时间优化,就要找出来编译耗时长的部分。 上文中提到了经过 Xcode 查看项目具体编译时间的方式,笔者也放了以下部分示意图。

compileProcess detail

3、减小项目编译时间的考虑

1. 调整 Xcode 的Build Settings 中的配置

关于调整 Xcode 的 Build Settings 中的配置,笔者查询资料后发如今 Xcode10 及以前调整空间比较大,在 Xcode11 的时候,笔者初步尝试后,发现调整 Xcode 的 Build Settings 中的配置对于优化项目编译时间影响不大。

2. 把稳定三方打包成 Framework

笔者在分析了项目编译时间后,发现 QiShareDemo 中引入的每一个三方都各自花费了20s+的时间,记不清是查看了网上的文章示例仍是如何,想到了若是在使用这些三方的过程当中,不会频繁改动这些三方源代码的状况下,能够把这些三方打包成 Framework,尝试解决编译耗时久的问题。 通过尝试把项目中的三方打成 Framework,供 QiShareDemo 使用后,就获得了一个明显的减小编译耗时的成效。 从开始的笔者在 clone 了 QiShareDemo 后,全量编译编译项目的编译时间为105.207s; 后来通过笔者初步把三方打包成 Framework 后,全量编译项目的时间缩短为44.573s;

2.1 浅谈编译耗时缩短的缘由
2.1.1 把稳定三方打成 Framework 对编译影响

能够结合上一篇文章 浅谈编译过程来谈这个问题。 关于项目直接使用 Framework ,会减小编译时间的缘由,组内同窗 沐灵洛奇舞647 都说起过,笔者推测缘由是: 从编译过程来看,项目直接使用 Framework 相比使用 Cocoapods 的源代码依赖,就省了预编译、词法分析、语法分析、生成中间代码、生成目标文件的过程。因此就减小了编译时间。(编译过程更多信息可查看 浅谈编译过程) 这部分还有一个劣势,组内同窗 大成小栈 提到说,打成Framework 后在调试修改源代码的时候就不方便了。这个是必然的,因此最好是把那些稳定的三方打包成 Framework ,或者是和组内同窗分工合做,分别负责某个三方。

2.1.2 Objective-C 和 Swift 混编耗时影响

组内同窗 沐灵洛 还结合着笔者发出的编译过程图,说起过Swift 和 OC 项目混编相对于纯 Swift 项目可能耗时更多的问题。 这部分笔者的推测是看 Swift 项目的编译过程。若是只是单纯的 Swift 项目,编译的前端过程用 Swift 编译器就够用了。 若是是Swift 和 OC 混编的项目,编译的前端过程还会用到 Clang ,Clang 会把 C、Objective-C 的 API 向Swift API 作一个对应。我想这个过程多少会比 Swift 编译器单纯编译Swift 代码多一些编译耗时的增长。 下边笔者放了一个Swift Compiler 架构图,笔者是以流程图的方式绘制制做的Swift Compiler 架构图。

SwiftCompilerArchitecture.png

注:在以前的文章 浅谈编译过程中笔者介绍了 GCC、LLVM编译器,Swift 语言的编译器是用的自有的Swift Compiler。

3. 使用工具查看项目中代码编译耗时

可使用工具 BuildTimeAnalyzer-for-Xcode 查看项目中本身写的代码的编译时间。 笔者使用 BuildTimeAnalyzer-for-Xcode 查看了项目编译时间,找出了2处编译时间耗时的地方。 下图是笔者使用 BuildTimeAnalyzer-for-Xcode 查看出的项目编译时间耗时状况。 笔者在Target -> Build Settings -> Swift Compiler 的 Other Swift Flags 中添加了以下配置:

-Xfrontend -warn-long-function-bodies=100
-Xfrontend -warn-long-expression-type-checking=100
-Xfrontend -debug-time-function-bodies
复制代码

上述配置内容用于添加使用 BuildTimeAnalyzer-for-Xcode 的配置,用于查看出方法或表达式编译耗时超过100ms的位置以警告的形式表现出来。

下边笔者举2个遇到的编译耗时的代码示例。

3.1 ??(nil-coalescing 空合并运算符) 及 ”+“拼接在一块儿的耗时

这种 “??” 和 “+”拼接字符串用在一块儿时,在编译过程当中会比较耗时。最好改为短短的小代码语句。

compileTime1

通过笔者把上述耗时代码使用 if let 的方式处理后,编译耗时的问题已获得了解决。

compileTime2

3.2 使用 snapkit 时候可能遇到的编译耗时

笔者打开了测出的使用 Snapkit 的过程当中,可能遇到的编译耗时的代码。检测编译耗时的示意图以下:

compileTime3

若是把上述的红色箭头指向的代码改为使用蓝色箭头指向的代码能够解决编译耗时的问题。 笔者收获是:使用Snapkit 布局的时候,参考值尽量是一个明确值,尽量不要设置参考的时候,再让编译器去帮咱们计算值,咱们能够尽量多的告诉编译器咱们知道的事情。

4、其余考虑方向

1. SwiftUI

使用SwiftUI能够实时查看代码显示效果,并能够在不一样设备上预览效果。 使用 SwiftUI 能够提升开发效率。 SwiftUI 官方教程:Learn to Make Apps with SwiftUI

2. Swift的HotReload尝试

考虑到市面上 Flutter 支持 HotReload 能够极大提高开发效率,其实Swift 也支持 Hot Reload ,目前笔者只试过 injectionIII Demo 的HotReload,目前不作过多介绍。 Swift 的 HotReload 尝试可使用工具 Injection III 。 以下网址中有 InjectionIII 的使用介绍及使用Demo。injectionIII Injection III App Store下载地址:apps.apple.com/cn/app/inje…

5、参考学习网址


了解更多iOS及相关新技术,请关注咱们的公众号:

image

可添加以下小编微信,并备注加入QiShare技术交流群,小编会邀请你加入《QiShare技术交流群》。

小编微信

关注咱们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
Swift 5.1 (14) - 初始化和反初始化
Swift 5.1 (15) - 可选连接
浅谈编译过程
深刻理解HTTPS
浅谈 GPU 及 “App渲染流程”
iOS 查看及导出项目运行日志
Flutter Platform Channel 使用与源码分析
开发没切图怎么办?矢量图标(iconFont)上手指南
DarkMode、WKWebView、苹果登陆是否必须适配?
奇舞团安卓团队——aTaller
奇舞周刊

相关文章
相关标签/搜索