Xcode .c 和 .m 文件构建缓慢

Xcode build slow for .c and .m files

将 OSX 更新到 High Sierra 并将 Xcode 更新到 9.2.0 后,大型项目的项目构建时间失控了。构建时间从大约 10 分钟增加到大约 120 分钟。

在研究过程中,我注意到 Xcode 产生了 xcexec 个子进程,这些子进程占据了 cpu 的大部分使用。 xcexec几乎所有的时间都花在调用系统close调用上。每个 xcexec 进程每分钟调用大约 200 万次关闭调用。

检查 xcexec 二进制文件后,这似乎是用于启动其他构建操作(例如 clang)的包装器工具。

我完全重新安装了 Xcode,没有任何变化。构建系统设置为默认值。

是什么导致了这种行为?

installation instructions for watchman 指示您像这样设置 kern.maxfiles

 $ sudo sysctl -w kern.maxfiles=10485760
 $ sudo sysctl -w kern.maxfilesperproc=1048576

在 macOS High Sierra 上,这两个值的默认设置为 131072。 Watchman 的建议是对内核的性能关键设置进行 80 倍的更改。调整这些值可能会导致不同的性能特征,尤其是对于文件繁重的操作,如编译。

Watchman修改限制,允许同时观看更多文件

然而,

Xcode 将开始为您的项目编制索引并打开尽可能多的文件(通过 kern.maxfiles)。在编译阶段,Xcode 启动 xcexec 这将关闭所有打开的文件描述符以进行索引,然后才启动构建步骤子进程。该操作几乎不需要时间。但是在更改 kern.maxfiles 之后它突然出现了。

我在 2015 年中期的 MBP、macOS 10.13.3、Xcode 9.2.0 上进行了基准测试。

根据我的基准测试 kern.maxfilesperproc 对 Xcode 的构建性能没有影响。

一旦 kern.maxfiles 高于 327680,Xcode 构建的性能就会受到严重影响。

如果你需要支持 watchman 更大的项目,我建议将 kern.maxfiles 设置为(没有大于)327680。

请注意,设置 kern.maxfilessysctl 不会在重新启动后保持不变。 Adjust the values/Library/LaunchDaemons/limit.maxfiles.plist.