我正在使用 Xcode 6 Beta 6。
这是一件困扰我已经有一段时间的事情,但现在已经到了几乎无法使用的程度。
我的项目开始拥有 65 个 Swift 文件和一些桥接的 Objective-C 文件(它们并不是问题的原因)。
似乎对任何一个 Swift 文件进行轻微修改(例如在应用程序中几乎不使用的类中添加一个简单的空格)都会导致为指定目标重新编译整个 Swift 文件。
经过深入调查,我发现几乎占用了 100% 编译器时间的是 CompileSwift
阶段,Xcode 在您的目标的所有 Swift 文件上运行 swiftc
命令。
我进行了进一步调查,如果我只保留带有默认控制器的应用程序委托,则编译非常快。但随着我添加越来越多的项目文件,编译时间开始变得非常缓慢。
现在仅有 65 个源文件,每次编译需要大约 8/10 秒钟。根本不够“swift”。
除了 这个 之外,我没有看到任何讨论此问题的帖子,但那是旧版本的 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更新
苹果公司增加了增量编译(以及许多其他编译器优化)。您需要将代码迁移到Swift 1.2才能看到这些好处,但是苹果在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
的更改是可以接受的),但因为FileB
被重新编译了,所以它也会重新编译FileC
,这很糟糕,因为FileC
从未在此处使用FileA
。因此,我希望他们能改进这个依赖树求解器... 我用这个示例代码打开了一个radar。
更新:使用Xcode 7 beta 5和Swift 2.0
昨天,苹果发布了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英特尔Core i7)上编译大约需要5/6分钟。
但是即使苹果声称:
Xcode不会在发生小更改时重新构建整个目标。(28892475)
显然,当我们检查这个无聊的东西(向项目的任何文件添加一个私有属性(私有)!)后,我们都笑了...
我想指出一下Apple开发者论坛上的这个帖子,其中有一些关于此问题的更多信息(以及偶尔得到的赞赏的苹果开发者交流)。
基本上,人们想出了一些方法来尝试改善增量构建:
- 添加项目设置
HEADER_MAP_USES_VFS
并将其设置为true
- 从您的方案中禁用
查找隐式依赖项
- 创建一个新项目并将文件层次结构移动到新项目中。
我将尝试解决方案3,但解决方案1/2对我们没有起作用。
在整个情况中真正具有讽刺意味的是,当我们遇到第一次编译缓慢的问题时,看着这个问题的第一篇帖子时,我们正在使用Xcode 6和我相信是Swift 1或Swift 1.1代码,现在大约两年过去了,尽管Apple有了实际改进,但情况与Xcode 6时一样糟糕。多么具有讽刺意味啊。
我真的非常后悔选择Swift而不是Obj / C来进行我们的项目,因为它带来了每日的挫败感。(我甚至转到了AppCode,但那是另一回事)
无论如何,我发现这个SO帖子在本文撰写时已经有32k+的浏览量和143个upvotes,所以我想我不是唯一一个遇到这种情况的人。坚持下去,尽管对这种情况感到悲观,但可能会有一些曙光。
如果您有时间(和勇气!),我想Apple欢迎有关此事的报告。
更新Xcode 9
今天偶然发现this。 Xcode悄悄引入了一个新的构建系统,以改善当前可怕的性能。您必须通过工作区设置启用它。
已经尝试过了,但在完成后将更新此帖子。看起来很有前途。
swift2
更新。我注意到我的结尾短语很令人困惑,我已经更新了它以使其更清晰。 - apouche