Swift 编译优化(3) - 编译配置

通过优化编译配置,降低编译时间。

一. 开启Swift全模块化

前提

如果你的项目是纯Swift项目,那么请忽略 SWIFT_WHOLE_MODULE_OPTIMIZATION的配置。

如果你的项目是OC和Swift混编项目,并以Swift开发为主,请继续阅读Swift全模块化。

1. 理解Swift全模块化

SWIFT_WHOLE_MODULE_OPTIMIZATION 是一个与Swift编译相关的Xcode构建设置。这个设置控制着Swift编译器是否使用"Whole Module Optimization"(WMO)模式来编译Swift代码。以下是这个设置的详细解释:

是什么?

WMO 是Swift编译器的一种优化模式,它在编译整个模块时进行更广泛和更深入的优化。在这种模式下,编译器会将整个Swift模块(通常是一个Xcode工程中的所有Swift文件)视为一个单元来进行编译和优化。

如何工作?

  • 非WMO模式(默认设置):编译器对每个Swift文件单独编译,然后链接这些编译后的文件。这种方式支持增量编译,即只重新编译改动过的文件,适合开发过程中快速迭代。
  • WMO模式:编译器在编译时考虑整个模块的所有代码,使其能够进行更全面的优化,比如更好的函数内联、死代码消除等。这通常能提高最终应用程序的运行性能,但可能增加编译时间。

如何设置?

  • 设置为YES :启用 WMO。这通常在Release构建配置中使用,以提高应用程序的性能。
  • 设置为NO :禁用 WMO。这是Debug构建的常见设置,因为它支持更快的编译时间和更方便的调试。

总结

SWIFT_WHOLE_MODULE_OPTIMIZATION 是一个重要的编译选项,它允许开发者在编译时间和应用性能之间做出权衡。正确的使用这个设置可以帮助提高应用程序的性能,但也需要注意它可能带来的编译时间增加和调试上的不便。

2. 事与愿违

如果你的项目是OC和Swift混编项目,应该会遇到这样的情况,就改动了一个文件的一点代码(可能就加了一个空行)。

如果这个文件是OC文件,那么编译速度会很快。如果这个文件是Swift文件,编译会比较久。了解到这个问题背后的原因,才可以用好SWIFT_WHOLE_MODULE_OPTIMIZATION

为什么改动一点Swift代码会导致变慢?

在使用Objective-C代码中引用Swift代码时,通常情况下是通过导入 xxx-Swift.h 头文件来实现的,该头文件包含了整个Swift模块的公开接口和符号的声明。

由于 xxx-swift.h 是由xcode自动生成的,它包含了整个Swift模块的公开接口,因此无法选择性地导入。如果你只希望引入部分Swift代码而不是全部代码,目前的方式是无法实现的。

这意味着,如果你想在Objective-C中使用Swit代码,目前的解决方案是将整个Swift模块导入到Objective-C中,无法只选择部分导入。

这也就是改动一点Swift代码,编译也会慢点原因。

3. 再看 WMO

它控制着编译是使用 增量编译 还是 全模块编译 。基于上面的分析,我们知道在混编项目中,Swift是 全量编译 的。

全模块编译的优点

  1. 更高级的优化:WMO允许编译器在整个模块范围内进行优化。在这种模式下,编译器可以更好地理解整个模块的代码结构,从而执行更有效的优化,比如内联函数、去除无用代码和更好的数据流分析。
  2. 减少编译时间:在非WMO模式下,Swift默认使用Incremental编译,这意味着它会编译每个单独的文件。虽然这在开发过程中对于单个文件的更改很有效,但在全模块优化中,编译器可以更全面地考虑所有的代码和它们之间的关系,这可以在某些情况下减少总体编译时间。
  3. 并行编译:WMO还可以提升并行编译的效率。在整个模块范围内,编译器可以更好地管理依赖关系,从而更有效地分配编译任务到不同的处理器核心。
  4. 优化链接过程:当整个模块作为一个整体来优化时,链接过程也可以得到优化。编译器可以更好地处理符号解析和优化,从而加速最终的二进制文件生成。

那么在这种情况下,开启 SWIFT_WHOLE_MODULE_OPTIMIZATION 会对编译优化提供支持。

4. 如何开启WMO?

通过 状态栏 -> Editor -> Build Setting -> Add User-Defined Settings 添加 key 为 SWIFT_WHOLE_MODULE_OPTIMIZATION 构建项,

然后将该值设置为YES。

二. Swift 编译最佳优化

Swift 语言的编译器是 swiftlang,同时也是基于 LLVM 后端的。Xcode 9.3 版本之后 Swift 编译器会提供新的选项来帮助减少 Swift 可执行文件的大小. 我们的 IDE-Xcode 提供给我们 3 个等级的编译选项

优化选项 说明
No optimization[-Onone] 不进行优化,能保证较快的编译速度
Optimize for Speed[-O] 编译器将会对代码的执行效率进行优化,一定程度上会增加包大小
Optimize for Size[-Osize] 编译器会尽可能减少包的大小并且最小限度影响代码的执行效率。 根据项目不同,大致可以优化掉 5% - 30% 的代码空间占用。 相比 -0 来说,会损失大概 5% 的运行时性能。

-Osize 根据项目不同,大致可以优化掉 5% - 30% 的代码空间占用。 相比 -0 来说,会损失大概 5% 的运行时性能。 如果你的项目对运行速度不是特别敏感,并且可以接受轻微的性能损失,那么 -Osize 就值得一用。

通过 Xcode -> Build Setting -> Swift Compiler - Code Generation -> Optimization Level 将该编译选项设置为

  • Debug 模式设置为[-Onone]
  • Release 模式设置为 [-Osize]

三. Debug下关闭dSYM的生成

生成 dSYM 会消耗大量时间,如果不需要的话,可以将 Debug Information Format 修改为 DWARF 。新项目的默认设置是 Debug 配置编译时不生成 dSYM 文件。

四. Build Active Architecture Only

Build Settings -> Architectures -> Build Active Architecture Only

该编译项用于设置是否只编译当前使用的设备(连线设备)对应的arm指令集

开启时,xcode 只会对当为当前 CPU 架构创建二进制文件,在开发阶段,我们只在真机或模拟器(Active Architecture)编译工程。

在 Release 的编译中,应该包含所有支持的 CPU 架构,因为该二进制文件将通过 App Store 下发到用户各种各样的设备上。确保在 Debug 配置下设置为 YES,在 Release 配置下设置为 NO

Xcode 编译源文件时,会根据 Header Search Paths 自动添加 -I 参数,如果递归引用的路径下子目录越多,-I 参数也越多,编译器预处理头文件效率就越低,所以不能简单的设置路径递归引用。同样 Framework Search Paths 也类似处理。

六. 减少不必要的编译脚本

相关推荐
missmisslulu21 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP1 天前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP1 天前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件1 天前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
奇客软件2 天前
如何从相机的记忆棒(存储卡)中恢复丢失照片
深度学习·数码相机·ios·智能手机·电脑·笔记本电脑·iphone
GEEKVIP2 天前
如何修复变砖的手机并恢复丢失的数据
macos·ios·智能手机·word·手机·笔记本电脑·iphone
一丝晨光2 天前
继承、Lambda、Objective-C和Swift
开发语言·macos·ios·objective-c·swift·继承·lambda
GEEKVIP3 天前
iPhone/iPad技巧:如何解锁锁定的 iPhone 或 iPad
windows·macos·ios·智能手机·笔记本电脑·iphone·ipad
KWMax3 天前
RxSwift系列(二)操作符
ios·swift·rxswift