如何在Xcode中减少构建时间/加速编译时间?

72

一般来说,有哪些策略可以用来减少任何Xcode项目的编译时间?我主要关心Xcode的特定策略。

我正在使用Xcode进行iPhone开发,我的项目越来越大。我发现编译/链接阶段开始花费比我想象中更多的时间。

目前,我正在采取以下措施:

  • 使用静态库使得大部分代码不需要每次清理和构建主项目时重新编译

  • 将大多数资源从应用程序中移除,并在可能的情况下使用iPhone模拟器中的硬编码文件系统路径进行测试,以避免资源在更改时需要不断打包。

我注意到“检查依赖项”阶段似乎比我想象中要花费更长的时间。如果有任何减少时间的技巧,也希望能够提供!

14个回答

56

通常来说,你能够做的最大的事情就是控制你包含头文件的数量。

在源代码中包含“额外”的头文件会极大地减缓编译速度。这也往往会增加依赖检查所需的时间。

此外,使用前向声明而不是让头文件包含其他头文件可以极大地减少依赖项的数量,并有助于优化所有的计时。


24

谢谢您的博客文章,步骤易于跟随。 - elliotrock
@elliotrock 我很高兴这仍然有帮助(我本以为现在XCode使用更好的默认值)。 - fons
即使过了几年,你的DWARF TIP仍然让人惊叹,@fons。看起来你已经离开了Spotify,而这仍然是让人难以置信的呢 :) - Fattie
@fons 那静态库呢?在发布版本中,它们没有dSYM是没有意义的。在我的情况下,大部分代码都在静态库中,只有在构建最终二进制文件(将所有这些静态库链接到我的项目中)时才有dSYM是有意义的。 - Pavel P
谷歌搜索得到的答案是:“对于静态库或对象文件产品,不需要dSYM文件,也不会创建dSYM文件”- 因此,对于静态库来说,拥有dSYMs就没有任何意义。 - Pavel P

17

我个人为我的Mac开发项目切换到了LLVM-Clang编译器,并看到了在构建时间上的显著降低。还有LLVM-GCC编译器,但我不确定这是否会有助于构建时间,如果LLVM-Clang在iPhone应用程序编译时无法工作,您也可以尝试使用它。

我不确定LLVM是否支持iPhone上的开发,但我记得在新闻中读到过。这不是您可以在代码中实现的优化,但值得一试!


谢谢您的建议。我做了一些搜索,听起来应该可以工作,并且已经集成到XCode中(至少3.2版)。无论是否当前由我的项目使用都是我要检查的事情,因为我猜旧的XCode项目文件可能仍然默认使用旧的“纯gcc”方法。谢谢! - Brad Parks
我从未成功地使用LLVM编译iPhone。它真的被支持吗? - MrMage
它不支持iPhone,但在模拟器构建中可以正常工作,您只需要根据SDK条件化设置即可。 - Louis Gerbarg
1
这是有关XCode 3.2支持的不同编译器类型更多信息的链接:http://www.maccompanion.com/macc/archives/September2009/Columns/AccordingtoHoyle.htm。我还没有Snow Leopard(XCode 3.2需要?),但我认为我得考虑一下获取它。来自上述网址的引用:“如果您可以使用Clang,您将看到近三倍的性能提高,编译时间大大改善,比gcc的性能提高要大得多。(我可以听到旧的CodeWarrior用户现在叹息“终于!”)。但我不知道它是否适用于iPhone。” - Brad Parks

12

Xcode使用的线程数默认与您的CPU核心数相同。例如,一台搭载Intel Core i7处理器的Mac有两个核心,因此Xcode默认最多使用两个线程。由于编译时间通常受I/O限制而不是CPU限制,增加Xcode使用的线程数可以显著提高编译性能。

尝试将Xcode配置为使用3、4或8个线程,并查看哪一个在您的用例中提供了最佳性能。

您可以通过终端设置Xcode使用的进程数,方法如下:

defaults write com.apple.Xcode PBXNumberOfParallelBuildSubtasks 4

有关更多信息,请参见Xcode用户默认设置


3
此选项已不再存在。 - Duck

12
如果您的RAM不足8GB,请立即升级。我刚刚将我的MacBook Pro从4GB升级到了8GB。我的项目构建时间从2:10缩短到了0:45,这种提升让我感到非常震惊。它还可以使浏览网页更加顺畅,并提高Xcode在索引等方面的性能。

你知道这个策略是否适用于最近的XCode版本(例如4.5),因为我似乎注意到XCode内存使用量显著减少了吗? - user234736
3
我有16GB内存,但它仍然很慢。 - Hai Feng Kao
我有32GB,但它仍然很慢。 - Naresh
2.4GHz的i9处理器,搭配64GB内存,但仍然运行缓慢。 - firetrap

11
简单的回答:在您的本地网络上添加另一台运行Xcode的机器。 Xcode集成了distcc以进行分布式编译。它甚至可以使用Bonjour查找其他构建主机,这极大地简化了配置过程。对于大型构建,分发可以使您获得几乎与构建机器数量成正比的速度增加(2台机器需要一半的时间,三个需要三分之一,依此类推)。
要了解如何设置此项功能,您可以参考此开发文档。它还提供了其他有用的构建时间改进策略,例如使用预编译头文件和预测性构建。
编辑:不幸的是,似乎自Xcode 4.3以来,Apple已删除了此功能:http://lists.apple.com/archives/xcode-users/2012/Mar/msg00048.html Xcode 5具有服务器版本,可以进行CI,但我怀疑这对于特定开发人员构建不会产生任何好处。但是,还有一些未公布的功能应该可以显着加快构建时间。

1
我认为这并不会改善构建中检查依赖项的部分,只是编译而已。 - wbyoung
2
足够正确,但问题似乎开放了广泛的策略来改善编译时间,所以我认为它仍然相关。 - Tim Keating
我的经验是,添加额外的构建服务器实际上可能会增加构建时间。特别是,Xcode默认不在主机上进行构建,仅用于协调。因此,如果您坐在的机器与第二个盒子的速度相同或更快,则速度实际上会下降。即使在“正常”网络上分布了几台额外的机器(一个未针对构建农场进行优化的网络),我发现结果非常混乱。 - Rob Napier
有趣的见解...“没有默认主机”似乎是一个愚蠢的选择。我没有使用过带有任何规模代码库的Xcode分布式构建,但我曾经使用过distcc来处理一个相当大的Linux项目,即使添加了一个糟糕的机器也有所帮助。当然,它对链接时间没有任何帮助,因此如果您有一个需要进行大量链接工作的项目(例如具有大量模板的C++项目),那么这并不会真正帮助您。 - Tim Keating

8
我使用了一个脚本来利用RAM驱动器,结合一些“前向声明”优化,我的项目的干净构建时间从53秒缩短到20秒。
我曾想在AppStore上获取Gui,但最终选择了命令行。我将该脚本作为git存储库的一部分。
要查看构建时间,请在终端中输入以下内容: "defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES" 重新启动Xcode以在工具栏中注意到构建时间。 (这是我使用Objective-C的非干净构建时间) Cached build times 根据您的喜好调整脚本。- 请注意,该脚本会清除派生数据文件夹。
#!/bin/sh

#2 GIG RAM
GIGA_BYTES=$((2*1024*1024*1024))

# a sector is 512 bytes
NUMSECTORS=$((${GIGA_BYTES}/512))

#ram disk
mydev=`hdiutil attach -nomount ram://$NUMSECTORS`
newfs_hfs $mydev

# make mount point
MOUNT_POINT=/Users/your_user_name/Library/Developer/Xcode/DerivedData

# ******************************************* 
# ** WARNING - MOUNT POINT WILL BE DELETED ** 
# *******************************************
rm -rf ${MOUNT_POINT}
mkdir -p ${MOUNT_POINT}

# mount
mount -t hfs $mydev ${MOUNT_POINT}
echo unmount $(MOUNT_POINT)

查看效果和控制RAM驱动器:

mount                       - see mount points
umount mount_point          - unmount point
diskutil list               - see disks
diskutil eject /dev/diskX   - eject the disk
df -ahl                     - see free space

注意: 我基本上使用macOS提供的hdiutil。 我尝试打开-kernel选项(不交换到磁盘),但在我的机器上失败了,说它没有实现。

也许即将推出的新操作系统会带来更多改进,因为新的文件系统复制功能非常快,可能使这个脚本变得多余。


7

提高iOS项目编译速度的一个重要技巧是设置构建设置/架构/仅构建活动架构,至少可以把编译时间减半。

特别是在64位iPad和64位编译器出现后,此操作会不编译您当前未使用的架构的二进制文件。

在提交应用商店前一定要记得重新启用此设置,否则您的二进制文件将无法验证。


2
这是一个很好的建议,现在在Xcode中新项目的默认设置。请确保仅为Debug构建配置启用此设置,以便在归档(使用Release构建配置)时无需记住重新启用该设置。 - smileyborg

2

你提到使用静态库来避免编译最常用的文件。你可以通过将经常使用但不在静态库中的代码头文件放入预编译头文件中来实现类似的效果。至少它们只会被编译一次。

如果你的项目跨越多个编译类型(例如Obj-C、Obj-C++、C++),则必须小心避免出现问题。


2

一个词: TmpDisk

  1. 使用 TmpDisk 创建一个1.5Gb的RAM磁盘
  2. 将 Xcode > 首选项 > 位置 > 派生数据更改为 /Volumes/1.5Gb/xcode data
  3. 尽情享受速度吧!

3
不,这并没有改善任何事情,我已经测试过了。 - Mihailo Gazda
它确实起作用,效果非常显著!在2009年的MacBook Pro和2014年的11英寸Air上都是如此。只需尝试一下。如果您没有注意到任何变化,那么您可能没有正确更改路径。为什么?因为写入硬盘,甚至是SSD,需要时间。编译时,Xcode会写入相当多的内容。它还可以节省电池电量。唯一的缺点是RAM磁盘在工作几个小时后就会变满。然后我必须退出Xcode,删除文件,清空垃圾箱,然后重新开始。更大的RAM磁盘可以解决这个问题,但我的电脑只有8GB。 - Joaquim Paz Carvalho
我们不应该将项目文件复制到RAM磁盘中以获得最大效果吗? - Yaro
@MihailoGazda 在活动监视器中,Xcode 使用了多少 RAM? - user5306470

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接