为什么 swift 函数被编译了 25 次?

MrH*_*aze 9 xcode build ios swift

我意识到我的 iOS 项目(相当大,只有 swift 代码)需要很长时间来构建,所以我开始使用-debug-time-function-bodies和检查脚本日志来分析代码构建时间。

我注意到我的很多函数都编译了 25 或 26 次。

是什么导致了这种问题?

为了让这个问题更容易理解,这里有一个来自BuildTimeAnalyzer for Xcode的截图

在此处输入图片说明

正如你所看到的,occurrences一些函数被构建了 25 或 26 次。

Moj*_*ini 12

您提供的数据不足以说明实际原因是什么,但我将总结一些可能性。

发生的意义是什么?

这意味着编译器对一个方法、属性或表达式进行多次类型检查。


我应该如何知道该方法是什么、在哪里以及它需要多少时间?

通过启用这两个标志,您可以直接在代码中看到它们:

-Xfrontend -warn-long-expression-type-checking=100
Run Code Online (Sandbox Code Playgroud)
-Xfrontend -warn-long-function-bodies=100
Run Code Online (Sandbox Code Playgroud)

那是什么100的标志?

那是你意识到的最短时间。您可以从更高的数字开始,并在解决更昂贵的问题后逐步降低它。


我该如何解决?

通过告诉编译器您已经知道的内容,而不是让它自行推断。例如:

let singleString = myStrings.joined(separator: ";") /* takes around 200ms to compile */
let singleTypedString: String = myStrings.joined(separator: ";") /* Takes just 1ms to compile */
Run Code Online (Sandbox Code Playgroud)

如您所见,文字String将消除199 ms(在这一刻)

您可以在此答案中找到更复杂的示例其中代码的简单更改可节省大约2700 毫秒!


为什么编译器一遍又一遍地做呢?

似乎在较新的 Xcode 版本中进行了一些更改(我认为其中之一是并行构建等)导致了这一点。LLDB 和 Swift 语言开发人员正在努力提高性能,但我们可以自己帮助我们。

是否有任何解决方法可以防止多类型检查?

根据问题的来源(变量、函数、闭包、惰性等),有一些方法可以增强它。例如:

使一切final变得更好,并private在可能的情况下制作它们。这就是编译器知道您不会去执行的override方式,因此它只能进行一次类型检查。

这是您可以减少构建时间并防止编译器多次进行类型检查的方法。

希望能帮助到你。



还有一件事!:

根据Swift.org 中的这个链接

-Xfrontend,这促使了这篇文章。每个前端参数都被认为是不稳定的。所有这些。即使是与驱动程序选项相同的选项。我真的很想重命名它,但我也不知道该重命名什么。(更糟糕的是,Xcode 目前将它用于某些目的。你不想知道。)

所以第一,确保你只在调试模式下使用这些标志,第二,在解决你正在寻找的问题后关闭它们并不时尝试它们。