当配置“释放”时,Swift构建时间太长了?

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

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

但是当我使用Release配置构建项目时,它在Compile Swift源文件中停留了一个多小时.

我不知道这个,请帮帮我.

最佳答案 在DEBUG构建中,如果将所有花费在每个函数上的时间相加,那么大约需要7秒.这些数字并没有完全加起来 – 你花了142s来构建整个东西,但这些函数只需要大约7s来编译?

那是因为这些时间只是考虑每个函数体的类型检查.在Swift frontend中,您可以使用三个标志:

> -Xfrontend -debug-time-compilation
> -Xfrontend -debug-time-function-bodies
> -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!因此,没有必要考虑类型检查时间.我们可以进一步检查为什么LLVM使用-Xllvm -time-pass的速度很慢,但它不会给我们提供有用的信息,只是说X86汇编/对象发射器需要花费大部分时间.

让我们退后一步,检查哪些文件需要花费大部分时间来编译:

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中花了半分钟.这个文件出了什么问题?

>你有一个巨大的结构,有31个成员.仅编译该结构需要11秒.
>你有一个巨大的枚举,有80个变种.仅编译此枚举需要7秒.

第一个问题很容易解决:改为使用final类!第二个问题不会有一个简单的修复(我没有看到任何时间改进与替代品,例如用类层次结构替换枚举).所有其他慢速文件都有类似的问题:大结构,大枚举.

简单地用最终类替换所有结构就足以将编译时间从“超过几小时并仍在编译”到“2.5分钟”.

另见Why Choose Struct Over Class?.您的“结构”可能不符合结构.

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

点赞