[关闭]
@qidiandasheng 2020-07-12T17:09:46.000000Z 字数 4438 阅读 7775

如何加快编译速度

使用工具


如何查看编译时间

xcode界面直接查看

终端内输入:

  1. defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES

然后你在编译的时候点击xcode顶部的那个进度条,当编译完成的时候就能查看编译时间。

构建命令xcodebuild里查看

xcodebuild 是苹果发布自动构建的工具。直接在终端中使用xcodebuild即可进行编译打包,同时会有相关的编译输出结果,但是输出不太友好,难以观察。这里我们使用几个工具对输出结果,编译时间等进行一个友好的输出xcprettygnomontee

xcpretty是一个对输出结果进行格式化的工具,增强可读性。

  1. //安装
  2. gem install xcpretty

gnomon可以标记出每一个命令执行所消耗的时间。

  1. //安装
  2. npm install -g gnomon

tee可以把终端里的结果输出到文本文件中,同时终端中也保持输出。如果想要终端中不输出,只保存到文本文件中的话使用>把输出转向就可以了。

  1. //使用,ls是任何相关的终端命令,这里做演示用
  2. //保持终端输出
  3. ls | tee log.log
  4. //终端无输出
  5. ls > log.log
  1. //编译输入日志
  2. xcodebuild -workspace DSTestUtils.xcworkspace -scheme DSTestUtils | xcpretty | gnomon | tee log.log
  1. //对编译时间进行排序
  2. sort -n -k1 log.log
  3. Total 145.7656s
  4. 0.0000s
  5. 0.0000s
  6. 0.0000s
  7. 0.0000s
  8. 0.0000s
  9. 0.0000s
  10. .
  11. .
  12. .
  13. .
  14. 1.4617s Check Dependencies
  15. 1.6467s Compiling RCTNetworking.mm
  16. 1.6930s Compiling RCTJavaScriptLoader.mm
  17. 1.8876s Copying UIViewController+DSModulor.h
  18. 1.9461s Compiling RCTNetworking.mm
  19. 1.9636s Building library libDSModule.a
  20. 2.2466s Compiling Yoga.c
  21. 2.4131s Building Pods/AFNetworking [Release]
  22. 4.6648s Linking DSTestUtils

Optimization Level

这个是xcode Built Setting里的一个参数,Optimization Level是指编译器的优化层度,优化后的代码效率比较高,但是可读性比较差,且编译时间更长。 它一共有以下几个选项:

所以说我们平时开发的时候可以选择使用None来不给代码执行优化,这样既可以减少编译时间,又可以看出你代码哪里有性能问题。

而你的release版应该选择Fastest, Smalllest,这样既能执行所有的优化而不增加代码长度,又能使执行文件占用更少的内存。

pod里的Optimization Level

我们在使用pod的时候,每一个pod其实都是一个target,它有自己的Optimization Level。cocoapods默认给每一个pod的Optimization Level设置的是Fastest, Smallest,也就是说执行所有的优化和减少内存占用空间。

这样我们在开发的时候会有两个问题:一个是debug的时候无法输出pod源码里面的变量值,因为编译器已经给代码做了优化,它无法再记录你的变量值了。

还有一个就是编译时间长,拿我现在的工程来说,如果把所有pod的Optimization Level选项设置成None的话编译时间为2分30秒,如果为默认的Fastest, Smallest的话时间为3分15秒。

把所有pod的的Optimization Level设置为None只需在Podfile里加入以下代码即可(其中的"Dev"为你项目的Scheme):

  1. post_install do |installer|
  2. installer.pods_project.build_configurations.each do |config|
  3. if config.name.include?("Dev")
  4. config.build_settings['GCC_OPTIMIZATION_LEVEL'] = '0'
  5. end
  6. end
  7. end

平均节省时间45秒,20%


设置xcode编译的线程数

  1. defaults write xcodebuild PBXNumberOfParallelBuildSubtasks 8
  2. defaults write xcodebuild IDEBuildOperationMaxNumberOfConcurrentCompileTasks 8
  3. defaults write com.apple.xcode PBXNumberOfParallelBuildSubtasks 8
  4. defaults write com.apple.xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 8

XCode默认使用与CPU核数相同的线程来进行编译,但由于编译过程中的IO操作往往比CPU运算要多,因此适当的提升线程数可以在一定程度上加快编译速度。

平均节省时间15秒,8%


Debug Information Format

在工程对应Target的Build Settings中,找到Debug Information Format这一项,将Debug时的DWARF with dSYM file改为DWARF
这一项设置的是是否将调试信息加入到可执行文件中,改为DWARF后,如果程序崩溃,将无法输出崩溃位置对应的函数堆栈,但由于Debug模式下可以在XCode中查看调试信息,所以改为DWARF影响并不大。这一项更改完之后,可以大幅提升编译速度。

其实Debug Information Format就是表示是否生成.dSYM文件,也就是符号表。如果为DWARF就表示不生成.dSYM文件。

This setting controls the format of debug information used by the developer tools. [DEBUG_INFORMATION_FORMAT]

DWARF - Object files and linked products will use DWARF as the debug information format. [dwarf]
DWARF with dSYM File - Object files and linked products will use DWARF as the debug information format, and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). [dwarf-with-dsym]

下面这句虽然能修改所有pod的Debug Information FormatDWARF,但是是没用的,主要还是看主工程里的Debug Information Format的设置。主工程如果为DWARF with dSYM file也会为pod里的代码生成符号表的。如上面的官方描述所说如果为.a的静态文件的话是不会生成符号表的

  1. post_install do |installer|
  2. installer.pods_project.targets.each do |target|
  3. target.build_configurations.each do |config|
  4. if config.name == 'Dev'
  5. config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf'
  6. end
  7. end
  8. end
  9. end

平均节省时间7秒,5%


将Build Active Architecture Only改为Yes

这一项设置的是是否仅编译当前架构的版本,如果为No,会编译所有架构的版本。需要注意的是,此选项在Release模式下必须为No,否则发布的ipa在部分设备上将不能运行。这一项更改完之后,可以显著提高编译速度。

  1. post_install do |installer|
  2. installer.pods_project.targets.each do |target|
  3. target.build_configurations.each do |config|
  4. if config.name == 'Dev'
  5. config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES'
  6. end
  7. end
  8. end
  9. end

平均节省时间80秒,26%


二进制化

什么叫二进制化,其实就是把源码编译为静态库或动态库。也就是我们平常使用的.framework和.a文件,这些库都是已经编译好的,所以当你pod update或者pod install,就不用再重新编译一遍那么多文件了,能够显著减少编译时间。

如何进行二进制化请看我的这篇文章:。


小技巧

可以查看projectName.xcodeproj里的project.pbxproj文件。


新思路

发现第三方库在编译的时候会有缓存,在/Users/dasheng/Library/Developer/Xcode/DerivedData目录下,在这个目录下的其实就是编译好的二进制文件,在bulid clean的时候会把这部分的缓存给清除,那是否可以把对应的版本的保存起来,根据podfile.lock里的版本,到时候直接复制到这个缓存里面。

如何将iOS工程打包速度提升十倍以上

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注