Swift 项目编译优化(一)

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

一、名词简介

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

1. 全量编译

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

2. 增量编译

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

3. Swift Compiler

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

二、Swift 项目的编译过程

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

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

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

compileProcess1

笔者根据 Xcode 编译项目过程,做了如下 Swift 项目编译过程示意图。

SwiftCompileProcess.png

2. 查看项目编译时间

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

Xcode compile Time

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

compileProcess detail

三、减少项目编译时间的考虑

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 布局的时候,参考值尽可能是一个明确值,尽可能不要设置参考的时候,再让编译器去帮我们计算值,我们可以尽可能多的告诉编译器我们知道的事情。

四、其他考虑方向

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下载地址:https://apps.apple.com/cn/app/injectioniii/id1380446739?mt=12

五、参考学习网址

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350