概要
- Xcode 10でNew Build Systemが正式採用されデフォルト設定になったのですが、以前まで有効だった
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
で並列コンパイルの最大スレッド数の指定が機能していないような挙動だったので調べてみました。
結論
- New Build Systemは、
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
の影響を受けません。 - New Build Systemは、デフォルトで利用可能な最大のスレッド数(Hyper-Threadingも考慮される)で並列コンパイルされます。
- つまり、並列コンパイルに関しては手動での設定が不要となりました。
検証
- Legacy Build SystemとNew Build Systemでビルド時間を比較してみます。
- Xcodeのビルド時間は
ShowBuildOperationDuration
を設定することで表示されます。
- Xcodeのビルド時間は
- Build Systemの切り替えは、Xcodeのメニューの
File > Project Settings…
またはFile > Workspace Settings…
から設定可能です。

-
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
で設定した値は以下最大スレッド数
と記載します。
環境
- Xcode 10.1 (10B61)
- Swift 4.2
- iMac (Retina 5K, 27-inch, 2019) Intel Core i9-9900K 3600 MHz (8 cores)
対象のプロジェクト規模
- RxSwiftやRealmなどを含む3人月規模のプロジェクト
検証1: Indexingが終わった後にビルド
計測方法
- DerivedDataを削除し、初回のIndexingが終わった後にビルドを開始します。
結果
ビルドシステム | 最大スレッド数 | ビルド時間 |
---|---|---|
Legacy | 1 | 463.963 |
Legacy | 4 | 163.117 |
Legacy | 8 | 123.570 |
Legacy | 16 | 124.448 |
New | 1 | 89.440 |
New | 4 | 89.360 |
New | 8 | 89.848 |
New | 16 | 89.504 |
- ビルド時間は3回の平均値
考察
- New Build Systemは
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
の影響を受けておらず、ほぼ同一の計測結果でした。- 調べたところドキュメント等への記載は見つけられなかったのですが、ツイートしている人を発見。
- 少し本題からずれますが、Legacy Build Systemで8スレッドと16スレッドでビルド時間の差が出ていませんでした…(詳しくは後述)。
問題点
- New Build Systemのビルドが速いなーと思いつつ、何回もビルドするうちにビルド開始時のプログレスバーの初期位置が明らかにLegacyよりも進んでいることに気がつきました。そこでBuild with Timing Summaryで確認したところ、CompileSwiftSourcesがLegacyだと55 tasksだったのに対してNew Build Systemは5 tasksで、Indexingのタイミングで事前にコンパイルするタスク数の違いがあり、結果ビルド時間全体で差がついてしまったことがわかりました。
検証2: Indexingが開始される前にビルド
計測方法
- Indexingが終わった後だとCompileSwiftSourcesのタスク数に違いがあったため、今度はDerivedDataを削除し、Xcodeを起動直後のIndexingが始まる前にビルド(Build with Timing Summary)を開始します。
結果
ビルドシステム | 最大スレッド数 | ビルド時間 | Compile C | Compile Swift |
---|---|---|---|---|
Legacy | 1 | 792.610 | 341.848 | 410.295 |
Legacy | 4 | 214.919 | 373.098 | 327.548 |
Legacy | 8 | 153.421 | 491.378 | 422.904 |
Legacy | 16 | 153.310 | 827.944 | 662.014 |
New | 1 | 142.501 | 809.741 | 643.152 |
New | 4 | 142.652 | 808.462 | 641.644 |
New | 8 | 142.984 | 809.148 | 636.419 |
New | 16 | 143.610 | 822.892 | 652.259 |
- Compile CとCompile SwiftはTiming Summaryの結果
- すべてケースでCompileCは1038 tasks、CompileSwiftSourcesは91 tasksで同条件なことを確認
- 3回試行するにはビルド時間が長すぎたので1回実行した結果
考察
- New Build SystemのCompile C/SwiftがLegacy Build Systemの16スレッドとほぼ同じ結果になっていたので
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
を指定することなく利用可能な最大のスレッド数(16スレッド)が適用されていると言えそうです。 - New Build SystemはLegacy Build Systemより10%未満のビルド処理の向上がみられました。
おまけ
- New Build Systemを検証するきっかけはiMacを2017モデルから2019に変えたのでどれだけビルドが高速化するかを確認したかったのですが、
IDEBuildOperationMaxNumberOfConcurrentCompileTasks
を変更してもビルド速度に影響が出なかっため調べてみました。 - iMac 2017との比較結果は以下です。
比較対象のMac
- iMac (Retina 5K, 27-inch, 2017) Intel Core i7-7700K 4200 MHz (4 cores)
- iMac (Retina 5K, 27-inch, 2019) Intel Core i9-9900K 3600 MHz (8 cores)
結果
CPU | ビルドシステム | 最大スレッド数 | ビルド時間 | Compile C | Compile Swift |
---|---|---|---|---|---|
i7-7700K | Legacy | 4 | 267.478 | 460.486 | 431.874 |
i7-7700K | Legacy | 8 | 241.329 | 745.896 | 725.248 |
i7-7700K | New | 4 | 258.462 | 727.819 | 713.259 |
i7-7700K | New | 8 | 264.116 | 749.004 | 727.603 |
i9-9900K | Legacy | 8 | 153.421 | 491.378 | 422.904 |
i9-9900K | Legacy | 16 | 153.310 | 827.944 | 662.014 |
i9-9900K | New | 8 | 142.984 | 809.148 | 636.419 |
i9-9900K | New | 16 | 143.610 | 822.892 | 652.259 |
- i9-9900Kはi7-7700Kの1.6〜1.8倍程度の高速化となりました。
- i7-7700Kだと4スレッドから8スレッド(Hyper-Threading)に変更すると平均して10%くらい速くなっていました。ただi9-9900Kだとスレッド数を増やしても8スレッド以上はほぼ同じ結果になっていましたが、これは1コアのリソースを使い切ってしまいHyper-Threadingでパフォーマンスが向上する余地がなかったということなんですかね…? Hyper-Threadingを使いたくてi9-9900Kにしたので少し残念でした。