【问题标题】:Swift build time too long when the configuration is 'release'?配置为“发布”时,Swift 构建时间太长?
【发布时间】:2017-04-17 16:24:48
【问题描述】:

我有一个开源项目,项目中的文件数超过40个。

我在配置为Debug,编译时间为2m22s时构建项目。 而且我也用BuildTimeAnalyzer,时间最长的是28ms

但是当我使用Release 配置构建项目时,它卡在Compile Swift source files 一个多小时。

我对此一无所知,请帮助我。

【问题讨论】:

  • 请说明您使用的是哪个 Xcode 版本/swift 版本?
  • 我使用 xcode 8.2 以及 swift 2.3 和 swift 3。
  • 既然是“开源项目”,能否提供项目的源码?
  • 您是否使用干净构建或仅构建来测量构建时间 - 也许它正在消耗派生数据并因此加快构建时间?

标签: swift


【解决方案1】:

在 DEBUG 构建中,如果您将花费在每个函数上的所有时间加起来,您会得到大约 7 秒。这些数字加起来并不完全——你花了 142 秒来构建整个东西,但是这些函数只需要大约 7 秒来编译??

这是因为这些时间只是为了对每个函数体进行类型检查。在Swift frontend 中,您可以使用三个标志:

  1. -Xfrontend -debug-time-compilation
  2. -Xfrontend -debug-time-function-bodies
  3. -Xfrontend -debug-time-expression-type-checking

让我们用第一个来看看全貌。选择一个慢速文件,例如Option.swift,然后查看:

===-------------------------------------------------------------------------===
                               Swift compilation
===-------------------------------------------------------------------------===
  Total Execution Time: 30.5169 seconds (43.6413 wall clock)

   ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
  23.5183 ( 80.1%)   0.7773 ( 67.6%)  24.2957 ( 79.6%)  34.4762 ( 79.0%)  LLVM output
   3.7312 ( 12.7%)   0.0437 (  3.8%)   3.7749 ( 12.4%)   5.4192 ( 12.4%)  LLVM optimization
   1.8563 (  6.3%)   0.2830 ( 24.6%)   2.1393 (  7.0%)   3.1800 (  7.3%)  IRGen
   0.2026 (  0.7%)   0.0376 (  3.3%)   0.2402 (  0.8%)   0.4666 (  1.1%)  Type checking / Semantic analysis
... <snip> ...
  29.3665 (100.0%)   1.1504 (100.0%)  30.5169 (100.0%)  43.6413 (100.0%)  Total

原来慢的不是 Swift,而是 LLVM!因此,没有必要查看类型检查时间。我们可以使用-Xllvm -time-passes 进一步检查为什么 LLVM 很慢,但它不会给我们提供有用的信息,它只是说X86 Assembly / Object Emitter 占用了大部分时间。

让我们退后一步,看看哪些文件编译时间最长:

Option.swift             30.5169
Toolbox.swift            15.6143
PictorialBarSerie.swift  12.2670
LineSerie.swift           8.9690
ScatterSerie.swift        8.5959
FunnelSerie.swift         8.3299
GaugeSerie.swift          8.2945
...

Options.swift 中花费了半分钟。这个文件有什么问题?

  1. 你有一个巨大的结构,有 31 个成员。单独编译该结构需要 11 秒。
  2. 您有一个庞大的枚举,有 80 个变体。单独编译这个枚举需要 7 秒。

第一个问题很容易解决:改用final class第二个问题没有简单的解决方法(我看不到任何时间改进的替代方法,例如用类替换枚举等级制度)。所有其他慢速文件都有类似的问题:大结构、大枚举。

只需将所有struct 替换为final class 就足以将编译时间从“超过几小时且仍在编译”缩短到“2.5 分钟”。


另见Why Choose Struct Over Class?。您的“结构”可能不符合structs 的条件。

请注意,从struct 更改为类确实会改变用户代码的语义,因为类具有引用语义。

【讨论】:

    【解决方案2】:

    试试这个.... 在Build Settings -> Swift Compiler - Code Generation 下为您的Release 选择SWIFT_OPTIMIZATION_LEVEL = -Owholemodule。然后在Other Swift Flags 下输入-Onone。这样做为我的项目节省了大量时间。

    【讨论】:

      猜你喜欢
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多