Swift 编译优化(1) - 编译过程

背景介绍

自从混编Swift之后,Xcode编译的变慢了。主要体现在:

  • 切换分支,要编译好一会,动不动就卡死。
  • 改动一点Swift代码,也要编译好一会,苦不堪言。

团队的小伙伴也经常反馈编译慢的问题,一定程度上影响了开发效率。所以下定决心:好好优化一波。

作者的项目原本是OC项目,两年前进行Swift化,目前代码量再120万+行。

Swift化进度大概在70%。

OC代码逐步废弃过程中,本次编译优化,不包含OC相关的优化。

切换分支为什么变慢?

在Xcode中,当你切换分支,可能会导致编译时间大幅增加,原因主要包括以下几点:

  1. 缓存失效:Xcode使用一种高级缓存机制来优化编译时间。当你切换分支时,源代码会发生变化,这可能导致之前的编译缓存失效。因此,Xcode需要重新编译更多的文件,而不是仅仅那些自上次编译以来被修改过的文件。
  2. 项目依赖变化:不同分支可能有不同的项目配置和依赖关系。当你从一个分支切换到另一个分支时,这些配置和依赖的变化可能需要重新解析和编译。
  3. 索引重建:Xcode使用索引来支持诸如代码自动完成、快速跳转到定义等功能。分支切换可能导致Xcode需要更新或重建其索引,这个过程可能会占用额外的时间。
  4. 资源文件变化:如果不同分支中包含的资源文件(如图片、音频文件等)发生变化,Xcode可能需要更多时间来处理这些资源文件的变化。
  5. 清理和重建:在某些情况下,开发者在切换分支后可能会手动执行清理(Clean)操作,以确保从干净的状态开始编译。这意味着整个项目需要从头开始编译,自然会增加编译时间。

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

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

如果你只希望引入部分Swift代码而不是全部代码,目前的方式是无法实现的。由于 xxx-swift.h 是由xcode自动生成的,它包含了整个Swift模块的公开接口,因此无法选择性地导入。这意味着,如果你想在Objective-C中使用Swit代码,目前的解决方案是将整个Swift模块导入到Objective-C中,无法只选择部分导入。

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

编译过程

可以更详细地探讨 XCode 编译过程的每个阶段:

  1. 预处理 (Preprocessing)

    • 宏替换 :预处理器会处理以 #define 定义的宏,替换代码中的宏引用。
    • 文件包含 :处理 #include#import 指令,将头文件的内容插入到源文件中。
    • 条件编译 :根据 #if, #ifdef, #ifndef, #else, #elif, 和 #endif 指令,决定哪些部分的代码应该被编译。
    • 移除注释:预处理器会移除代码中的注释。
  2. 编译 (Compilation)

    • 语法检查:检查代码的语法是否符合编程语言规范。
    • 类型检查:验证变量和函数的数据类型,确保类型的正确性和一致性。
    • 生成中间代码:编译器生成中间表示(Intermediate Representation,IR)的代码,这个代码是平台无关的。
    • 优化:在生成目标代码之前,编译器会进行各种优化,比如循环优化,常量折叠等,以提高程序的运行效率。
  3. 汇编 (Assembly)

    • 生成汇编代码:编译器将中间代码转换成汇编语言。
    • 汇编成二进制代码:汇编器把汇编语言转换成机器码,即二进制代码,这是计算机可以直接执行的代码。
  4. 链接 (Linking)

    • 解析符号:链接器会解析程序中使用的函数和变量的引用,确保它们都指向正确的地址。
    • 合并对象文件:将所有的对象文件(编译生成的文件)和需要的库文件合并在一起,形成一个单一的可执行文件。
    • 地址分配:链接器为函数和变量分配内存地址,并解决程序内部和外部模块之间的引用。

在 Xcode 中,这些步骤通常是隐藏的,但可以通过构建日志来查看。Xcode 还提供了丰富的配置选项,允许开发者自定义编译过程,如设置不同的编译标志、选择不同的编译器和链接器选项等。此外,Xcode 集成了 LLVM 编译器,提供了先进的优化技术和调试支持。

相关推荐
I烟雨云渊T2 小时前
iOS 阅后即焚功能的实现
macos·ios·cocoa
struggle20252 小时前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift
Unlimitedz2 小时前
iOS视频编码详细步骤(视频编码器,基于 VideoToolbox,支持硬件编码 H264/H265)
ios·音视频
安和昂13 小时前
【iOS】SDWebImage源码学习
学习·ios
ii_best13 小时前
按键精灵ios脚本新增元素功能助力辅助工具开发(三)
ios
ii_best17 小时前
按键精灵ios脚本新增元素功能助力辅助工具开发(二)
ios
ii_best17 小时前
按键精灵ios脚本新增元素功能助力辅助工具开发(一)
ios
一丝晨光1 天前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift
Swift社区1 天前
Swift实战:如何优雅地从二叉搜索树中挑出最接近的K个值
开发语言·ios·swift
fydw_7151 天前
大语言模型RLHF训练框架全景解析:OpenRLHF、verl、LLaMA-Factory与SWIFT深度对比
语言模型·swift·llama