# 23.Swift项目编译速度优化

## 前言

本文将从代码层面探究如何分析并优化 `Swift` 代码的编译速度。

## 一、 检查代码中的编译瓶颈

### 1.1 项目配置

通过警告的形式标识出超出设定值的代码，下面以设置 `100ms` 为界限为例

在 `BuildSettings` 中 `other swift flags` 下添加下面的配置：

![1](/files/-Mj-GmsTeKvjmJmWP4B6)

* -Xfrontend -warn-long-function-bodies=100
* -Xfrontend -warn-long-expression-type-checking=100

> 仅在 `DEBUG` 下添加就行了，毕竟只是用来检测

### 1.2 编译检查

`Clean` 后编译一次，这里就可以看到很多的警告了：

![2](/files/-Mj-GmsWqU2MgE-M0Dkb)

![3](/files/-Mj-Gms_5KU-s7pyqXXW)

你可能觉得这样检测有点不方便，毕竟项目的警告可能有几百上千个。下面介绍一个工具：`BuildTimeAnalyzer-for-Xcode`

## 二、 BuildTimeAnalyzer-for-Xcode 使用说明

首先 Clone 项目代码（或者直接[下载代码](https://github.com/RyukieSama/BuildTimeAnalyzer-for-Xcode)）

```
git clone https://github.com/RyukieSama/BuildTimeAnalyzer-for-Xcode.git
```

### 2.1 项目配置

在 `BuildSettings` 中 `other swift flags` 下添加下面的配置：

* -Xfrontend -debug-time-function-bodies

然后 `Clean` 项目，重新 `Build`。

### 2.2 打开 BuildTimeAnalyzer.xcodeproj

这里有三种方式来使用

#### a. 直接运行

![直接运行](/files/-Mj-GmscDcFyO-z9-6p0)

#### b. 导出App

`Product - Archive`

![导出App](/files/-Mj-GmsdgO7iAOv1nzRT)

导出一个App文件，以后即可直接使用了。

![App](/files/-Mj-Gmsf1R3j7ZJqFvsl)

#### c. 懒人方式-下载即用

这里我搞好了一个包，直接可用。支持 `Intel`， `Apple Silicon`。

[下载：BuildTimeAnalyzer.zip即可](https://github.com/RyukieSama/BuildTimeAnalyzer-for-Xcode)

### 2.3 查看编译耗时日志

![04](/files/-Mj-Gmspjhv7krsRS9_n)

在列表中点击刚才自己的配置完成并编译后的项目，即可查看日志。

![05](/files/-Mj-GmsvzI7i65ftB7Kh)

显示了整体编译耗时，还标有具体代码的行数与函数名，点击可跳转。

> 每次时间不一定一样，根据电脑运行情况会有一些变化，但是整体的瓶颈趋势还是基本一致的

## 三、 优化项目

这里个人建议结合上面两种方式来定位。

* `BuildTimeAnalyzer` 用来找到瓶颈更加直观
* 第一个直接添加警告的方式用来定位具体代码更准确

### 3.1 项目配置

为了结合两种方式，这里我的配置如下：

![09](/files/-Mj-Gmt-TsJxKrdffhO5)

***`BuildTimeAnalyzer`\*\*\*\* \*\*\*\*分析结果***

![我的电脑配置](/files/-Mj-Gmt3LEFNiYi6gJNE)

![12](/files/-Mj-Gmt6nfrtKoHe3h2v)

* 最高： `DataBaseDataCenter+Overview` 耗时 `35075ms`

### 案例1：较长的逻辑

![10](/files/-Mj-Gmt9e-E7qXT7aOrl)

这里是使用 `WCDB` 瓶颈显示的是连续的调用 `WCDB` 中的范型函数来获得一个 `condition` 进行数据库操作。

![11](/files/-Mj-GmtAp6efLEXk96tT)

#### 优化：拆分

![14](/files/-Mj-GmtB676bIkUdCu9x)

Clean 后再 Build，查看是否有效：

![15](/files/-Mj-GmtCazvMb7jYsnot)

`DataBaseDataCenter+Overview` 耗时由 `35075ms` 下降至 `19007ms`，减少了近一半的时间。那么再把 `DataBaseDataCenter+Overview` 其他相同场景的代码也优化一下看看结果吧。

![16](/files/-Mj-GmtDljgaYPyB8JiM)

优化了另一处一样的场景后，时间降到了 `915ms`。

### 案例2：字符串拼接

这里使用了 `+` 进行字符串的拼接

![19](/files/-Mj-GmtFk_S-Ry0OPcPb)

![17](/files/-Mj-GmtGiFZrg60u-CUo)

此处总耗时 `2596ms`。

#### 优化：使用 "xx\\(xx)xx" 拼接

使用 `\(preString)~\(endString)` 的方式进行拼接

![20](/files/-Mj-GmtH2vUzYAgW4HRs)

![18](/files/-Mj-GmtJiahm7hcqXR1m)

效果明显，降到了 `617ms`。

### 案例3：少用 ??

![22](/files/-Mj-GmtKcnBlbwA7LaV8)

![21](/files/-Mj-GmtLYJR8YQzdbHT-)

此处用了较多的 `??`。整体耗时 `3561ms`。

#### 优化：提前 gurad/if let 解包或者减少调用 ?? 次数

![23](/files/-Mj-GmtMIyl7sHkOkOVN)

![24](/files/-Mj-GmtN32dhHdYzInlf)

整体降到了 `855ms`。

## 四、 总结

此处列举了一些我在项目中的一些成功优化的点，当然还有一些没有找到合适优化方式的点。再有一些有价值的点结局的话我会再来更新进文中。而且这里是以个人项目作为小白鼠进行的优化，企业项目中一般可优化的地方就更多了。而且我们也不能为了优化而优化，不能影响了源代码的可读性与连贯性。

也欢迎大家交流补充

## 参考

* [BuildTimeAnalyzer中文手册](https://github.com/RyukieSama/BuildTimeAnalyzer-for-Xcode)
* [配置说明](https://github.com/apple/swift/commit/18c75928639acf0ccf0e1fb6729eea75bc09cbd5)
* [iOS 微信编译速度优化分享](https://mp.weixin.qq.com/s/-wgBhE11xEXDS7Hqgq3FjA)
* [Optimizing Swift build times](https://github.com/RyukieSama/Optimizing-Swift-Build-Times)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ryukiedev.gitbook.io/wiki/swift/23.swift-xiang-mu-bian-yi-su-du-you-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
