本文翻译自:Profiling your Swift compilation timesswift
我遇到一个问题。我正在开发的一个全新的应用-是100%用Swift来写的。考虑到这个项目只有大概200个文件,我注意到它须要的编译时间超过了个人想象,更重要的是,它比前几个星期的编译速度慢了不少。在这个问题变得愈来愈糟糕以前,我须要尽快找到问题的根源。数组
第一步是添加 -Xfrontend -debug-time-function-bodies
这个Swift 编译选项:xcode
这会让这个编译器输出一个函数编译的时长(感谢Kevin Ballard 给我这个线索)。这个编译日志能够在Xcode 的 Report 窗口中看到,但须要你手动一个个展开每一个文件:闭包
下一步为了理解它们,须要把全部这些日志聚合在一个文件。app
咱们使用 xcodebuild
命令工具来把全部的日志输出到控制台:frontend
# Clean and build, capturing only lines containing `X.Yms` where X > 0, sorting from largest to smallest xcodebuild -workspace App.xcworkspace -scheme App clean build | grep [1-9].[0-9]ms | sort -nr > culprits.txt
接下来就是在这些输出中找到我想要的信息。我发现有超过1200行的数据是编译超过3秒的,谢天谢地的是这么多行都是三个相同的函数重复不少次(我对编译器不是很懂,不明白为何会出现这种状况,可是输出的数据中包含了“closure”闭包这个关键词仍是提供了一些线索)函数
3158.2ms /Users/Bryan/Projects/App/FileA.swift:23:14 @objc get {} 3157.8ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3142.1ms /Users/Bryan/Projects/App/FileA.swift:23:14 @objc get {} 3141.6ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3139.2ms /Users/Bryan/Projects/App/FileA.swift:23:14 @objc get {} 3138.7ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3128.3ms /Users/Bryan/Projects/App/FileB.swift:27:22 final get {} 3109.9ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3052.7ms /Users/Bryan/Projects/App/FileA.swift:23:14 @objc get {} 3052.6ms /Users/Bryan/Projects/App/FileA.swift:23:14 @objc get {} 3052.2ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3052.1ms /Users/Bryan/Projects/App/FileA.swift:23:52 (closure) 3049.0ms /Users/Bryan/Projects/App/FileB.swift:27:22 final get {} 3026.1ms /Users/Bryan/Projects/App/FileB.swift:27:22 final get {}
更疯狂的是,全部这三个函数都是一行简单的代码。重写这三行代码就可让个人项目编译时间快60%。我知道这不少人不爽,可是老实说,我很是高兴弄清楚了到底是什么缘由,若是下次遇到一样的问题,我知道本身该怎么作了。工具
你可能想知道这个三行代码是什么。这三行代码都很是类似,相似下面的:性能
return [CustomType()] + array.map(CustomType.init) + [CustomType()]
我不能肯定形成这个问题是由于数组的 append 操做,或者mapping 操做,仍是二者的结合。我放弃使用这些函数,不理会是否影响性能,添加了额外的临时变量和可变参数,用普通的方式改写。我不是第一个发现这个数组添加的操做很慢,就由于这样一行优雅,看似无害的代码让我亲身经历了这个痛苦。ui
Swift 仍然是一个很是年轻的语言,有这样的问题很正常,做为一个开放的社区,咱们应该互相帮助,防止另外一个痛苦发生。