こんにちは、ココナラiOSアプリ開発担当の小林です。
以前のブログで、ココナラiOSアプリのビルド時間改善への取り組みを紹介しました。その後リリースされたXcode10では以下の変更が行われ、ビルド時間が大幅に改善されています。
- Swiftコンパイラがバージョン4.2に対応
- 新しいビルドシステム(New Build System)が正式対応
今回はXcode10対応とともに行ったビルド設定の最適化と、その成果について紹介したいと思います。
ビルド時間は下記の環境で計測を行っています。
- MacBook Pro (15-inch, 2018)
- 2.2 GHz Intel Core i7 (6-core)
- 16 GB 2400 MHz DDR4
- 256GB NVMe SSD
- macOS Mojave 10.14.1
- Xcode 9.4 / Xcode 10.1
Xcode9.4時点の状況
Xcode9.4ではあまりの差分ビルドの遅さから、いわゆる Whole Module Optimization
を利用したビルド時間改善の設定を行って開発を進めており、このときのDebugビルド時間は次のとおりでした。
- フルビルド: 122s
- 差分ビルド: 56.8s (コード変更の大小に関わらず、ほぼ一定)
Releaseビルド(Archive)は以下のとおりほぼデフォルトの設定ですが、3490sとなんと1時間近くかかっています。
- Whole Module Optimization
Optimization Level
: 最適化(-O)を実施Architecture
は armv7/arm64Bitcode
をON
当初はBitriseでReleaseビルドを生成していたのですが、ビルド時間の上限である90分をオーバーしてしまい、利用できなくなるという事態に陥っていました😭
Xcode10対応の実施内容
Xcode10対応に際し、まずSwift4.2に対応するためのコンバート作業を行った後、いくつかの設定項目について見直しを行いました。
New Build System
に最適化する
File
メニューにある Workspace Settings...
を選択すると、以下のようなシートダイアログが表示されます。
ここで Build System
の設定が New Build System
になっていれば、新しいビルドシステムが利用されます。
さらに、これまで Whole Module Optimization
を利用してDebugビルドの時間改善を行っていた場合は、これを Incremental
に戻します。
この設定に関する詳細は Building Faster in Xcode@WWDC 2018 にて言及されています。
最適化を-Osize
に変更する
Xcode9の頃も -Osize
は指定できましたが、コンパイラがクラッシュする不具合があり採用できませんでした。Xcode10で改めて指定したところ問題はなさそうでしたので、Releaseビルドに採用しました。
Objective-Cのコードに対して最適化をかけたい場合は、
Apple Clang - Code Generation
の配下にあるOptimization Level
を変更します。
最新のビルド時間
コンパイラのアップデートとビルド設定の見直しにより、Debugビルドの時間は以下のようになりました。
- フルビルド: 77.6s
- 差分ビルド: 12s〜40s (ファイルの変更内容は規模により変動)
特に差分ビルドが大幅に改善され、かなりストレスが軽減された印象です😇
またReleaseビルドについても 1044s と、従来の3倍☄️以上 高速化することができました!
ビルド中の負荷について
Releaseビルド中のCPUにかかる負荷を観察していると、次の傾向があることが分かりました。
- Whole Module Optimizationの前処理 (SIL optimizer)
- 最大2プロセス(armv7およびarm64用)が稼動
- 全体のビルド時間の中では僅か(2〜3分)
- コードコンパイルのメイン処理
- CPUの論理コア数(6-core HT対応CPUなら12)分のプロセスが稼動
- Bitcodeへの変換
- 最大2プロセスが稼動し続ける
- 全体のビルド時間の大半を占める
"2"の段階においてはCPUリソースを使い切っていました。
一方"1"と"3"の段階ではTurbo Boostは発動しているものの、CPUリソースには余裕があるようです。
つまり、CPUコア数を増やした場合は"2"の高速化は期待できますが、"1"と"3"の高速化は、Turbo Boostのクロック数によることになります。 そして"3"の傾向から、Bitcodeを使用している場合、CPUコア数の多いMacを使用しても、ビルド時間が想定よりも改善しないこともありそうです。
まとめと課題
改善前後の結果をまとめると、以下のようになりました。
Before | After | 性能改善 | |
---|---|---|---|
Debugビルド(差分) | 56.8s | 12〜40s | 1.4〜4.7x |
Debugビルド(フル) | 122s | 77.6s | 1.6x |
Releaseビルド | 3490s | 1044s | 3.3x |
下記のポイントで、ビルド設定の見直すと良さそうです。
- Xcode10でのDebugビルドは
New Build System
とIncremental
ビルドの使用を推奨 - AdHoc配信等で古い端末での検証が不要なら、
arm64
版のみをビルドする Bitcode
の出力には時間を要し、CPUコア数の恩恵は少ない。急ぎの場合はOFFにすることも検討
Bitcode
出力に関するログを観察すると、異様に時間のかかっているファイルがいくつかありました。コンパイラが苦手とするパターンがあるかもしれないので、さらに分析を進めれば、よりビルド時間を改善することができそうです。
正直なところ、Xcode10への移行とビルド設定を見直すだけでこれだけビルド時間が改善されるとは想像していませんでした。「金の弾丸」を導入するのも有効ではありますが、まず自プロジェクトの傾向を分析し、ソフトウェアレベルでの改善を実施してみてはいかがでしょうか。