为什么 Swift 的类型检查器如此缓慢

主要观点:

  • Swift 编译器因类型推断导致编译表达式时间过长,如在一些复杂表达式中,约束求解器可能会陷入困境,即使代码最终能成功编译,也可能花费很长时间。
  • 例如在包含多种枚举和函数重载的代码中,以及使用ExpressibleBy协议和运算符重载的表达式中,都会导致类型组合增多,影响编译速度。
  • 可以通过运行特定命令来查找代码中导致编译时间过长的部分,使用临时变量拆分慢表达式,或添加相关编译设置来警告长表达式的编译时间。
  • Swift 团队已意识到该问题,并在[已知问题区域]中列出,目前的指数级最坏情况难以避免,需要采用不同的类型检查方法来解决。
  • 提出了一系列可能的解决方案,如添加编译器标志切换到新的类型检查器、制作添加类型注解的工具等。

关键信息:

  • Swift 编译器的类型推断机制在处理复杂表达式时性能不佳,会导致编译时间过长,如在 12 行代码上 Swift 6 可能花费 42 秒,而 Clang 可在相同时间内进行 38 次干净构建。
  • 示例代码中setThreatLevel函数和midnight枚举值的歧义,以及+运算符在不同类型间的操作导致的编译问题。
  • 可通过将channel转换为字符串来解决编译问题,使代码在 0.19 秒内成功编译。
  • 约束求解器的性质可能导致找到意外的解决方案或性能不可预测,如添加“+ 1”后编译时间变为 0.7 秒。

重要细节:

  • 介绍了 Swift 编译器的类型检查相关内容,如[Type Checker Design and Implementation]文档和[swift/lib/Sema 文件夹]中的源代码。
  • 提供了查找代码中慢编译部分的命令xcodebuild clean build -project <YOUR PROJECT FILE NAME>.xcodeproj/ OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-expression-type-checking" | grep -Ei '^\d+\.\d+ms\t/.+$' | sort -r,以及添加编译设置-Xfrontend-warn-long-expression-type-checking=100来警告长表达式编译时间。
  • 提及 Swift 团队在[known problem areas]中列出的问题以及目前无法避免指数级最坏情况,需要新的类型检查方法来解决。
  • 提出了一系列解决该问题的步骤,包括添加编译器标志、制作工具、更新示例代码、添加 Xcode 功能等。
阅读 12
0 条评论