首页 > 解决方案 > 为什么 swift 函数被编译 25 次?

问题描述

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

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

什么可能导致这种问题?

为了让这个问题更容易理解,这里是Xcode 的 BuildTimeAnalyzer的截图

在此处输入图像描述

正如您在occurrences某些功能下看到的那样,构建了 25 或 26 次。

标签: iosswiftxcodebuild

解决方案


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

发生的意义是什么?

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


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

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

-Xfrontend -warn-long-expression-type-checking=100
-Xfrontend -warn-long-function-bodies=100

100旗帜里的那是什么?

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


我该如何解决?

通过告诉编译器你已经知道什么而不是让它自己推断。例如:

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

如您所见,写作String类型将消除199 ms(此时)

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


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

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

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

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

让一切都final变得更好,private尽可能让它们变得更好。这就是编译器知道你不会去override它的方式,所以它可以只进行一次类型检查。

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

希望能帮助到你。



还有一件事!:

根据Swift.org 中的这个链接

-Xfrontend,这促使了这篇文章。每个前端参数都被认为是不稳定的。他们所有人。即使是与驱动程序选项相同的选项。我真的很想重命名它,但我也不知道如何重命名它。(更糟糕的是,Xcode 目前使用它来做一些事情。你不想知道。)

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


推荐阅读