为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Swift编译时间这么慢?

为什么Swift编译时间这么慢?

猛跑小猪 2019-12-09 09:11:06
我正在使用Xcode 6 Beta 6。这已经困扰了我一段时间,但是现在已经到了几乎无法使用的地步。我的项目已经开始有一个体面的65个斯威夫特文件的大小和几个桥接Objective-C的文件(这是真的不是问题的原因)。似乎对任何Swift文件进行任何微小的修改(例如在应用中几乎未使用的类中添加简单的空白)都会导致重新编译指定目标的整个Swift文件。经过更深入的研究后,我发现CompileSwiftXcode在swiftc目标的所有Swift文件上运行命令的阶段占了编译器时间的几乎100%。我做了进一步的调查,如果仅使用默认控制器保留应用程序委托,则编译速度非常快,但是随着我添加越来越多的项目文件,编译时间开始变得很慢。现在只有65个源文件,每次编译大约需要8/10秒。一点也不快。我还没有看到任何帖子谈到这个问题,除了这一个,但所以我想知道如果我在这种情况下,只有一个,这是一个旧版本的Xcode 6。我已经在GitHub上检查了一些Swift项目,例如Alamofire,Euler和CryptoSwift,但是它们都没有足够的Swift文件可以进行实际比较。我发现唯一一个启动时大小合适的项目是SwiftHN,即使它只有十几个源文件,我仍然能够验证同一件事,一个简单的空间,整个项目需要重新编译,这开始需要一个很少的时间(2/3秒)。与分析器和编译都快速发展的Objective-C代码相比,这确实让Swift永远无法处理大型项目,但是请告诉我我错了。Xcode 6 Beta 7更新仍然没有任何改善。这开始变得荒谬。由于缺少#importSwift,我真的看不到苹果将如何进行优化。不要像我那样高兴得太快。他们用来使构建增量的图形求解器尚未得到很好的优化。的确,首先,它并不关注函数签名的更改,因此,如果在一个方法的块中添加空格,则将重新编译所有依赖该类的文件。现在,如果您进行修改FileA,则编译器显然会标记FileA为要重新编译。它还将重新编译FileB(根据对的更改,这将是可以的FileA),而且还FileC因为FileB重新编译了,这很糟糕,因为在此FileC从未使用FileA过。因此,我希望他们能改进依赖关系树求解器...我已经用此示例代码打开了雷达。Xcode 7 beta 5和Swift 2.0更新昨天,Apple发布了Beta 5,在发布说明中我们可以看到:Swift语言和编译器•增量构建:仅更改函数的主体将不再导致依赖文件的重建。(15352929)我已经尝试过了,我必须说它现在真的(真的!)运行良好。他们迅速优化了增量构建。我烈建议您创建一个swift2.0分支,并使用XCode 7 beta 5使代码保持最新。您会对编译器的增强功能感到满意(但是我会说XCode 7的全局状态仍然很慢且有错误)。Xcode 8.2更新自从我最近一次更新此问题以来已经有一段时间了。现在,我们的应用程序大约有2万行代码,几乎都是Swift代码,虽然不错,但并不出色。它经历了迅速的2迁移,而不是迅速的3迁移。在2014年中的Macbook pro(2.5 GHz Intel Core i7)上进行编译大约需要5 / 6m,这在干净的版本上还可以。但是,尽管苹果声称:增量构建仍然是一个笑话:仅发生很小的更改时,Xcode不会重建整个目标。(28892475)显然,我认为我们很多人在检查了这个废话之后就笑了(向我项目的任何文件添加一个私有(私有!)属性都会重新编译整个过程……)我想指出你们在Apple开发人员论坛上的这个线程,该线程上有关于此问题的更多信息(以及不时地对此事的Apple开发人员的交流)基本上人们想出了一些方法来尝试改进增量构建:将HEADER_MAP_USES_VFS项目设置添加到true禁用Find implicit dependencies您的方案创建一个新项目,然后将文件层次结构移至新项目。我将尝试解决方案3,但解决方案1/2不适用于我们。具有讽刺意味的是,在整个情况下,有趣的是,当我们遇到第一个编译缓慢问题时,尽管我们从Apple那里获得了实际的改进,但在第一篇文章中,我们使用的是Xcode 6和Swift 1或Swift 1.1代码。这种情况与Xcode 6一样糟糕。实际上,我真的很后悔为我们的项目选择Swift而不是Obj / C,因为它每天都会令人沮丧。(我什至改用AppCode,但这是另一个故事)无论如何,截至撰写本文时,我看到这则SO帖子具有32k +的视图和143个ups,所以我想我不是唯一的一个。尽管对这种情况感到悲观,但还是呆在那儿,隧道尽头可能有些亮光。
查看完整描述

3 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

如果您试图确定特定的文件来减慢编译时间,则可以尝试通过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但是输出的内容非常冗长且难以使用。


查看完整回答
反对 回复 2019-12-09
  • 3 回答
  • 0 关注
  • 930 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信