为啥 Swift 编译时间这么慢?
Posted
技术标签:
【中文标题】为啥 Swift 编译时间这么慢?【英文标题】:Why is Swift compile time so slow?为什么 Swift 编译时间这么慢? 【发布时间】:2014-10-21 15:43:59 【问题描述】:我正在使用 Xcode 6 Beta 6。
这已经困扰我一段时间了,但它现在已经到了几乎无法使用的地步。
我的项目开始有一个体面大小的 65 个 Swift 文件和一些桥接的 Objective-C 文件(这真的不是问题的原因)。
似乎对任何 Swift 文件的任何轻微修改(例如在应用程序中几乎不使用的类中添加一个简单的空格)都会导致指定目标的整个 Swift 文件被重新编译。
经过深入调查,我发现占用编译器时间几乎 100% 的是 CompileSwift
阶段,在该阶段 Xcode 对目标的所有 Swift 文件运行 swiftc
命令。
我做了一些进一步的调查,如果我只使用默认控制器保留应用程序委托,编译速度非常快,但是随着我添加越来越多的项目文件,编译时间开始变得非常慢。
现在只有 65 个源文件,每次编译大约需要 8/10 秒。一点也不迅速。
除了this one,我没有看到任何关于这个问题的帖子,但它是 Xcode 6 的旧版本。所以我想知道是否只有我一个人在这种情况下。
更新
我检查了GitHub 上的一些 Swift 项目,例如 Alamofire、Euler 和 CryptoSwift,但没有一个有足够的 Swift 文件来进行实际比较。我发现的唯一一个开始具有体面大小的项目是SwiftHN,即使它只有十几个源文件,我仍然能够验证同样的事情,一个简单的空间和整个项目需要重新编译,这开始需要一点时间(2/3 秒)。
与分析器和编译速度都非常快的 Objective-C 代码相比,这确实感觉 Swift 永远无法处理大型项目,但请告诉我我错了。
使用 Xcode 6 Beta 7 更新
仍然没有任何改善。这开始变得荒谬了。由于 Swift 中缺少 #import
,我真的不知道 Apple 将如何优化这一点。
使用 Xcode 6.3 和 Swift 1.2 更新
Apple 添加了incremental builds(以及许多其他编译器优化)。您必须将代码迁移到 Swift 1.2 才能看到这些好处,但 Apple 在 Xcode 6.3 中添加了一个工具来帮助您这样做:
但是
不要像我一样高兴得太快。他们用来进行增量构建的图形求解器尚未得到很好的优化。
首先,它不会查看函数签名的更改,因此如果您在一个方法的块中添加一个空格,所有依赖于该类的文件都将被重新编译。
其次,它似乎是根据重新编译的文件创建树,即使更改不会影响它们。例如,如果将这三个类移动到不同的文件中
class FileA: NSObject
var foo:String?
class FileB: NSObject
var bar:FileA?
class FileC: NSObject
var baz:FileB?
现在如果你修改FileA
,编译器显然会将FileA
标记为重新编译。它还将重新编译FileB
(根据对FileA
的更改,这将是可以的),但是还有FileC
,因为FileB
被重新编译,这非常糟糕,因为FileC
从不在这里使用FileA
。
所以我希望他们改进依赖树求解器...我用这个示例代码打开了radar。
使用 Xcode 7 beta 5 和 Swift 2.0 更新
昨天 Apple 发布了 beta 5,在发行说明中我们可以看到:
Swift 语言和编译器 • 增量构建:仅更改函数体不应再导致依赖文件重新构建。 (15352929)
我已经尝试过了,我必须说它现在真的(真的!)运行良好。他们极大地优化了 swift 中的增量构建。
我强烈建议您创建一个 swift2.0
分支并使用 XCode 7 beta 5 使您的代码保持最新。您会对编译器的增强感到高兴(但是我想说 XCode 7 的全局状态仍然是慢且有问题)
使用 Xcode 8.2 更新
自从我上次更新这个问题以来已经有一段时间了,所以在这里。
我们的应用程序现在大约有 20k 行几乎完全是 Swift 代码,这很不错,但并不出色。它经历了 swift 2 和 swift 3 迁移。在 2014 年中期的 Macbook pro(2.5 GHz Intel Core i7)上编译大约需要 5/6m,这在干净的构建上是可以的。
尽管 Apple 声称,增量构建仍然是一个笑话:
当仅发生很小的更改时,Xcode 不会重建整个目标。 (28892475)
显然,我认为我们中的许多人在检查完这些废话后只是笑了(向我的项目的任何文件添加一个私有(私有!)属性将重新编译整个事情......)
我想向你们指出 Apple 开发者论坛上的 this thread,其中包含有关该问题的更多信息(以及不时感谢 Apple 开发者就此事进行的交流)
基本上人们想出了一些办法来尝试改进增量构建:
-
添加一个
HEADER_MAP_USES_VFS
项目设置设置为true
从您的方案中禁用 Find implicit dependencies
创建一个新项目并将文件层次结构移至新项目。
我会尝试解决方案 3,但解决方案 1/2 对我们不起作用。
在整个情况下具有讽刺意味的有趣之处在于,在查看有关此问题的第一篇文章时,我们使用 Xcode 6 和我相信 swift 1 或 swift 1.1 代码,当时我们遇到了第一次编译缓慢,而现在大约两年后,尽管实际改进了Apple 的情况与 Xcode 6 一样糟糕。真是讽刺。
我真的真的后悔为我们的项目选择了 Swift 而不是 Obj/C,因为它每天都会带来挫败感。 (我什至切换到 AppCode 但这是另一回事)
无论如何,我看到这篇 SO 帖子在撰写本文时有 32k+ 的浏览量和 143 次浏览量,所以我想我不是唯一一个。尽管对这种情况持悲观态度,但请坚持下去,隧道尽头可能会有一些曙光。
如果你有时间(和勇气!),我猜 Apple 很欢迎你对此有所了解。
下次见!干杯
使用 Xcode 9 更新
今天偶然发现this。 Xcode 悄悄地引入了一个新的构建系统来改进当前糟糕的性能。您必须通过工作区设置启用它。
已经尝试过,但完成后会更新这篇文章。不过看起来很有希望。
【问题讨论】:
有趣!不知是缺少优化还是因为没有接口文件需要解析这么多文件。 有类似的问题,最后我意识到这是因为实体类中使用自定义运算符从 JSON 反序列化。如果你正在使用any,我建议你尝试一个一个转换为正常功能,看看是否有任何变化。 自 XCode 6 beta 6 以来,我的项目中的编译变得非常缓慢。我不确定这是由于 beta 的更改还是由于我的代码。但我的项目还不算大(约 40-50 个 Swift 文件)。 随着我的项目的增长,编译变得非常缓慢。我还依赖于几个 pod,我确信这会激怒这个问题。这是使用最近的非测试版。 增量构建仍然是在“保守的依赖分析中进行的,因此您可能仍然会看到比绝对必要的更多的文件重建”。希望随着时间的推移会有所改善。 【参考方案1】:好吧,事实证明 Rob Napier 是对的。是一个文件(实际上是一种方法)导致编译器出错。
现在不要误会我的意思。 Swift 每次都会重新编译你所有的文件,但现在很棒的是,Apple 在它编译的文件上添加了实时编译反馈,所以 Xcode 6 GM 现在可以实时显示正在编译的 Swift 文件和编译状态如您在此屏幕截图中所见:
因此,了解您的哪些文件需要这么长时间非常方便。就我而言,就是这段代码:
var dic = super.json().mutableCopy() as NSMutableDictionary
dic.addEntriesFromDictionary([
"url" : self.url?.absoluteString ?? "",
"title" : self.title ?? ""
])
return dic.copy() as NSDictionary
因为属性title
的类型为var title:String?
而不是NSString
。将其添加到 NSMutableDictionary
时,编译器会发疯。
改成:
var dic = super.json().mutableCopy() as NSMutableDictionary
dic.addEntriesFromDictionary([
"url" : self.url?.absoluteString ?? "",
"title" : NSString(string: self.title ?? "")
])
return dic.copy() as NSDictionary
使编译时间从 10/15 秒(甚至更多)缩短到一秒......太棒了。
【讨论】:
感谢您跟进解答。这对于其他追查类型推断引擎在编译期间陷入困境的人来说可能非常有用。 你从哪里得到这个视图@apouche?我在 xcode 中没有看到它 需要打开调试助手(CMD+8)点击当前构建 是的,我相信 Apple 稍后会对此进行优化,否则在 swift 中进行现实世界的项目注定会在这里和那里。 我怎样才能使用这个工具来显示正在编译的文件?【参考方案2】:我们已经尝试了很多方法来解决这个问题,因为我们有大约 10 万行 Swift 代码和 30 万行 ObjC 代码。
我们的第一步是根据函数编译时间输出优化所有函数(例如这里描述的https://thatthinginswift.com/debug-long-compile-times-swift/)
接下来我们编写了一个脚本将所有 swift 文件合并到一个文件中,这打破了访问级别,但它使我们的编译时间从 5-6 分钟缩短到了 ~1 分钟。
该功能现已失效,因为我们向 Apple 询问了此问题,他们建议我们应该执行以下操作:
-
在“Swift 编译器 - 代码生成”构建设置中打开“整个模块优化”。选择
'Fast, Whole Module Optimization'
-
在“Swift 编译器 - 自定义标志”中,为您的开发构建添加
'-Onone'
设置这些标志后,编译器将一步编译所有 Swift 文件。我们发现我们的合并脚本比单独编译文件要快得多。但是,如果没有 '-Onone'
覆盖,它也会优化整个模块,速度较慢。当我们在其他 Swift 标志中设置 '-Onone'
标志时,它会停止优化,但不会停止一步编译所有 Swift 文件。
有关整个模块优化的更多信息,请在此处查看 Apple 的博文 - https://swift.org/blog/whole-module-optimizations/
我们发现这些设置允许我们的 Swift 代码在 30 秒内编译 :-) 我没有证据表明它在其他项目上如何工作,但如果 Swift 编译时间仍然是一个问题,我建议尝试一下给你。
请注意,对于您的 App Store 构建,您应该保留 '-Onone'
标志,因为建议对生产构建进行优化。
【讨论】:
非常感谢您的建议!我只是不明白为什么官方资料中没有类似的东西(至少很容易找到),例如你提到的文章应该(必须!)有关于-Onone
的评论。我们现在不能使用整个模块优化,因为它会使编译器崩溃......但是你的建议几乎可以提高我们的构建速度 10 倍。在 MacBook Air(每年 2013 年)上,它的构建时间约为 8 分钟,现在已降至约 1 分钟,其中一半时间用于在目标之间切换(我们有应用程序、扩展程序和少量内部框架)和编译故事板
我也测试过这个方法,它是唯一提到的包含 -Onone 的方法,它确实显着减少了构建时间。
也和我一起工作。使用-Onone
有助于减少构建时间。非常感谢朋友!【参考方案3】:
这可能与您的项目规模无关。它可能是一些特定的代码,甚至可能只有一行。您可以通过尝试一次编译一个文件而不是整个项目来测试这一点。或者尝试查看构建日志以查看哪个文件花费了这么长时间。
作为可能导致问题的代码种类的示例,this 38-line gist 在 beta7 中编译需要一分钟以上。都是这一块造成的:
let pipeResult =
seq |> filter~~ $0 % 2 == 0
|> sorted~~ $1 < $0
|> map~~ $0.description
|> joinedWithCommas
只需一两行即可简化它,它几乎可以立即编译。问题是这会导致编译器的指数增长(可能是阶乘增长)。显然这并不理想,如果您可以隔离此类情况,您应该打开雷达来帮助清理这些问题。
【讨论】:
我不确定您是否看到了我对CompileSwift
阶段的评论。即使只修改了一个文件,它也会占用所有 swift 文件。因此,如果它是一个需要一些时间的文件(我非常怀疑),编译器永远不会告诉你它是哪一个。
您可以使用swiftc
编译单个文件以查看它们需要多长时间。
我很抱歉没有给你赏金,因为我一开始并不相信。我也尝试过一个一个的编译文件,但是这样做很麻烦(每次都必须正确地提供框架和deps)所以我放弃了。请查看我对这篇文章的最新回答以获得完整的解释
我不认为这是基于项目规模的。我的项目只有 4 个 swift 文件,并且突然开始编译非常慢。昨天灯火很快。除了添加图标和启动图像之外,我对我的项目所做的任何事情都无法说明。【参考方案4】:
如果您尝试识别会减慢编译时间的特定文件,您可以尝试通过xctool 从命令行编译它,这将为您提供逐个文件的编译时间。
需要注意的是,默认情况下,它会为每个 CPU 内核同时构建 2 个文件,并且不会给您“净”经过的时间,而是绝对的“用户”时间。这样一来,并行文件之间的所有时间都会变得均匀,并且看起来非常相似。
要克服这个问题,将 -jobs
标志设置为 1,这样它就不会并行化文件构建。这将花费更长的时间,但最终您将获得“净”编译时间,您可以逐个文件进行比较。
这是一个可以解决问题的示例命令:
xctool -workspace <your_workspace> -scheme <your_scheme> -jobs 1 build
“编译 Swift 文件”阶段的输出类似于:
...
✓ Compile EntityObserver.swift (1623 ms)
✓ Compile Session.swift (1526 ms)
✓ Compile SearchComposer.swift (1556 ms)
...
从此输出中,您可以快速确定哪些文件的编译时间比其他文件要长。此外,您可以高精度地确定您的重构(显式强制转换、类型提示等)是否降低了特定文件的编译时间。
注意:从技术上讲,您也可以使用 xcodebuild
执行此操作,但输出非常冗长且难以使用。
【讨论】:
只要确保你的项目的整体模块优化设置为 false,否则它不会分离出单独的 swift 文件。 见Swift Compiler
→ Optimization Level
Fast, Whole Module Optimization [-O -whole-module-optimization]
【参考方案5】:
就我而言,Xcode 7 完全没有区别。我有多个函数需要几秒钟来编译。
示例
// Build time: 5238.3ms
return CGSize(width: size.width + (rightView?.bounds.width ?? 0) + (leftView?.bounds.width ?? 0) + 22, height: bounds.height)
解开可选项后,构建时间减少了 99.4%。
// Build time: 32.4ms
var padding: CGFloat = 22
if let rightView = rightView
padding += rightView.bounds.width
if let leftView = leftView
padding += leftView.bounds.width
return CGSizeMake(size.width + padding, bounds.height)
在this post 和this post 中查看更多示例。
Xcode 构建时间分析器
我 developed an Xcode plug-in 对于遇到这些问题的人可能会派上用场。
Swift 3 中似乎有一些改进,所以希望我们能看到我们的 Swift 代码编译得更快。
【讨论】:
太棒了,希望我能给你超过+1。你是真的,你的插件也很棒。我已经使用了它并且我的构建时间正在减少,这意味着超快速的开发,因为这个选项有时是噩梦并导致编译器变慢。 太棒了!你的工具对我帮助很大。谢谢 很棒的插件 - 真的很有用!谢谢 @Robert Gummesson,我们有任何用于 Objective-C 代码的工具吗?【参考方案6】:可能我们无法修复 Swift 编译器,但我们可以修复的是我们的代码!
Swift 编译器中有一个隐藏选项,可以打印出编译器编译每个函数所需的确切时间间隔:-Xfrontend -debug-time-function-bodies
。它使我们能够发现代码中的瓶颈并显着缩短编译时间。
在终端中简单运行以下命令并分析结果:
xcodebuild -workspace App.xcworkspace -scheme App clean build OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" | grep [1-9].[0-9]ms | sort -nr > culprits.txt
很棒的 Brian Irace 写了一篇关于它的精彩文章 Profiling your Swift compilation times。
【讨论】:
对于首先使用 zshalias grep='noglob grep'
的人,否则 grep 将不起作用【参考方案7】:
解决方案是强制转换。
我有一大堆字典,像这样:
["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
.....
编译它大约需要 40 分钟。直到我把字典改成这样:
["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
....
这几乎适用于我遇到的关于我硬编码到我的应用程序中的数据类型的所有其他问题。
【讨论】:
嗯,是的,这是您为缩短编译时间而进行的优化的一部分,但当前 swift 编译器的主要问题仍然是,每次您进行最轻微的修改时,它仍然会重新编译所有单个 swift 文件. 如果不是那么悲伤的话,那就好笑了。【参考方案8】:需要注意的一点是,Swift 类型推理引擎对于嵌套类型可能会非常慢。您可以通过查看需要很长时间的各个编译单元的构建日志,然后将完整的 Xcode 生成的命令复制并粘贴到终端窗口中,然后按 CTRL-\ 来获得有关导致缓慢的大致信息一些诊断。查看http://blog.impathic.com/post/99647568844/debugging-slow-swift-compile-times 获取完整示例。
【讨论】:
这对我来说是最好的答案(见链接)。我可以很容易地找到存在问题的两条不同的线,并通过将我的线分解成更小的线来解决它。 这是一个非常有用的答案,因为它显示了如何找到编译器发疯的地方。在我的情况下,它是以下内容: 'curScore[curPlayer%2]+curScore[2+curPlayer%2]==3 && maker%2==curPlayer%2' 一旦我将它从 'if' 移动到 'let ',导致“表达式太复杂,无法在合理的时间内解决;考虑将表达式分解为不同的子表达式” 这绝对是解决这个问题最有用的方法。【参考方案9】:还要确保在编译调试(Swift 或 Objective-C)时,您设置为 Build Active Architecture Only:
【讨论】:
【参考方案10】:由于所有这些东西都处于测试阶段,并且由于 Swift 编译器(至少截至今天)尚未开放,我想您的问题没有真正的答案。
首先,将 Objective-C 与 Swift 编译器进行比较在某种程度上是残酷的。 Swift 仍处于测试阶段,我确信 Apple 致力于提供功能和修复错误,而不是提供闪电般的速度(你不会通过购买家具开始建造房屋)。我猜苹果会在适当的时候优化编译器。
如果由于某种原因必须完整编译所有源文件,则可以选择创建单独的模块/库。但是这个选项目前还不可能,因为 Swift 在语言稳定之前不能允许库。
我的猜测是他们会优化编译器。出于同样的原因,我们无法创建预编译模块,很可能编译器需要从头开始编译所有内容。但是一旦语言达到稳定版本并且二进制文件的格式不再改变,我们将能够创建我们的库,也许(?)编译器也将能够优化它的工作。
不过,只是猜测,因为只有 Apple 知道......
【讨论】:
“出于同样的原因,我们无法创建预编译模块,很可能编译器需要从头开始编译所有内容。”很好的观察,以前没有这样想过。 2017 仍然很慢 2017 年使用 Xcode 9 和新的构建系统,但仍然很慢 2018 年使用 Xcode 9,我有一个包含 50 多个 swift 文件的项目,如果我进行干净构建,现在已经过了 5 分钟,我的编译还没有完成。【参考方案11】:对于 Xcode 8,进入项目设置,然后编辑器 > 添加构建设置 > 添加用户定义设置,并添加以下内容:
SWIFT_WHOLE_MODULE_OPTIMIZATION = YES
对于一个 40KLOC 的 swift 项目,添加此标志后,我们的 clean-build 编译时间从 7 分钟缩短到了 65 秒,这是奇迹。还可以确认 2 位朋友在企业项目中看到了类似的改进。
我只能假设这是 Xcode 8.0 中的某种错误
编辑:对于某些人来说,它似乎不再适用于 Xcode 8.3。
【讨论】:
请问“项目设置”在哪里? @Raniys 单击 Xcode 左窗格中根级别的蓝色图标。 我发现从 Xcode 8.3(非测试版)开始,这不再适用于我的情况 :(【参考方案12】:不幸的是,Swift 编译器仍未针对快速和增量编译进行优化(从 Xcode 6.3 beta 开始)。同时,您可以使用以下一些技术来改善 Swift 编译时间:
将应用程序拆分为框架以减少重新编译的影响。但请注意,您必须避免应用程序中的循环依赖。有关此主题的更多信息,请查看此帖子:http://bits.citrusbyte.com/improving-swift-compile-time/
将 Swift 用于项目中相当稳定且不经常更改的部分。对于需要经常更改的其他领域或需要大量编译/运行迭代才能完成的领域(几乎所有与 UI 相关的东西),最好使用具有混合搭配方法的 Objective-C。
尝试使用“Injection for Xcode”进行运行时代码注入
使用roopc方法:http://roopc.net/posts/2014/speeding-up-swift-builds/
通过显式转换提供一些提示来减轻快速类型推理引擎的负担。
【讨论】:
【参考方案13】:Swift 数组和字典的构造似乎是一个非常受欢迎的原因(特别是对于来自 Ruby 背景的你),也就是说,
var a = ["a": "b",
"c": "d",
"e": "f",
"g": "h",
"i": "j",
"k": "l",
"m": "n",
"o": "p",
"q": "r",
"s": "t",
"u": "v",
"x": "z"]
这可能是应该解决它的原因:
var a = NSMutableDictionary()
a["a"] = "b"
a["c"] = "d"
... and so on
【讨论】:
【参考方案14】:对于调试和测试,请确保使用以下设置将编译时间从大约 20 分钟缩短到不到 2 分钟,
-
在项目构建设置中,搜索“优化”
将 Debug 设置为“Fastest[-O3]”或更高。
为活动架构设置构建:是
调试信息格式:DWARF
整个模块优化:否
我浪费了无数个小时等待项目构建,结果却意识到我必须做出一点改变,并且不得不再等 30 分钟来测试它。这些是对我有用的设置。 (我仍在尝试设置)
但是,请确保您至少将“DWARF with dSYM”(如果您想监控您的应用程序)和 Build Active Architecture 设置为“NO”,以便发布/存档推送到 iTunes Connect(我记得在这里浪费了几个小时也)。
【讨论】:
我可能是错的,但是设置提高的优化级别实际上不会增加构建时间吗?优化级别将提高运行时性能。Set Build for Active Architecture: YES
使我的编译时间减少了大约 45%。非常感谢。【参考方案15】:
编译器花费大量时间来推断和检查类型。所以添加类型注释对编译器有很大帮助。
如果你有很多像这样的链式函数调用
let sum = [1,2,3].map(String($0)).flatMap(Float($0)).reduce(0, combine: +)
然后编译器需要一段时间来确定sum
的类型应该是什么。添加类型会有所帮助。也有助于将间歇性步骤拉入单独的变量中。
let numbers: [Int] = [1,2,3]
let strings: [String] = sum.map(String($0))
let floats: [Float] = strings.flatMap(Float($0))
let sum: Float = floats.reduce(0, combine: +)
特别是对于数字类型CGFloat
、Int
有很大帮助。像2
这样的文字数字可以表示许多不同的数字类型。所以编译器需要从上下文中找出它是哪一个。
还应避免使用像+
这样需要花费大量时间查找的函数。使用多个+
连接多个数组很慢,因为编译器需要确定应该为每个+
调用+
的哪个实现。所以尽可能使用var a: [Foo]
和append()
。
您可以添加警告以检测which functions are slow to compile in Xcode。
在 Build Settings 中为您的目标搜索 Other Swift Flags 并添加
-Xfrontend -warn-long-function-bodies=100
对编译时间超过 100 毫秒的每个函数发出警告。
【讨论】:
这仍然是真的吗?设置类型可以加快速度? @eonist 是的,添加类型意味着编译器不必进行类型推断。这将始终保持明显更快。【参考方案16】:对于混合了Objective-C和Swift代码的项目,我们可以在Other Swift Flags
中设置-enable-bridging-pch
。有了这个,桥接头只解析一次,结果(一个临时的“预编译头”或“PCH”文件)被缓存并在目标中的所有 Swift 文件中重用。苹果声称它将构建时间减少了 30%。 Reference Link:
注意:这仅适用于 Swift 3.1 及更高版本。
【讨论】:
【参考方案17】:重新启动我的 Mac 确实解决了这个问题。仅通过重新启动,我就从 15 分钟的构建时间缩短到了 30 秒的构建时间。
【讨论】:
【参考方案18】:Swift 编译时间was improved in new Xcode 6.3
编译器改进
Swift 1.2 编译器经过精心设计,更加稳定并改进了 各方面的表现。这些变化也提供了更好的 在 Xcode 中使用 Swift 的经验。一些最明显的 改进包括:
增量构建
未更改的源文件将不再被重新编译 默认值,这将显着缩短最常见的构建时间 案例。可能仍需要对代码进行较大的结构更改 需要重建多个文件。
更快的可执行文件
调试版本生成的二进制文件运行速度相当快,而且新的 优化提供了更好的发布构建性能。
更好的编译器诊断
更清晰的错误和警告消息,以及新的 Fix-it,使其成为可能 更容易编写正确的 Swift 1.2 代码。
稳定性改进
最常见的编译器崩溃已得到修复。您还应该看到 Xcode 编辑器中的 SourceKit 警告更少。
【讨论】:
【参考方案19】:在一个表达式中混合使用 integer 文字和 float 文字也会导致编译时间过长。
1.0 + (1.0 + (1 * (1.0 + 1.0))) // 3429ms
1.0 + (1.0 + (1.0 * (1.0 + 1.0))) // 5ms
在我在整数文字后面加上.0
之后,许多 1000+ms 编译时表达式减少到 10~100ms。
【讨论】:
【参考方案20】:这是另一种可能导致类型推断速度大幅下降的情况。 合并运算符。
换行如:
abs(some_optional_variable ?? 0)
到
abs((some_optional_variable ?? 0) as VARIABLE_TYPE)
帮助将我的编译时间从 70 秒缩短到 13 秒
【讨论】:
【参考方案21】:在 Xcode 6.3.1 中没有什么对我有用 - 当我添加了大约 100 个 Swift 文件时,Xcode 随机挂在构建和/或索引上。我尝试了模块化选项,但没有成功。
安装和使用 Xcode 6.4 Beta 确实对我有用。
【讨论】:
【参考方案22】:这对我来说就像魔术一样 - Speed Up Swift Compilation。它将编译时间从 10 分钟缩短到 3 分钟。
它说你应该打开Whole Module Optimization
,同时在Other Swift Flags
中添加-Onone
。
我在Xcode 8.3
/Xcode 8.2
上使用Swift 3
。
【讨论】:
以上是关于为啥 Swift 编译时间这么慢?的主要内容,如果未能解决你的问题,请参考以下文章