ObjecTips

Swift & Objective-C で iOS とか macOS とか

Swift の enum の型の明記とビルド速度

調査の動機

Swift って結構省略して書けるけどその分 Xcode が脳内補完するからビルドが遅くなるんじゃないの?
だったら省略表記無しでコードが長くなってもビルド速度が早い方がいい。
エビデンスが無いので一応確認してみよう。

ビルド環境

ビルド環境
本体 iMac (Retina 5K, 27-inch, Late 2014)
プロセッサ 3.5 GHz Intel Core i5
メモリ 24 GB 1600 MHz DDR3
Xcode Xcode 10.0

比較コード

enum の型を明記するパターン

cell.accessoryType = UITableViewCell.AccessoryType.checkmark

enum の型を省略するパターン(こちらの記述が一般的)

cell.accessoryType = .checkmark

比較手順

let cell: UITableViewCell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "")
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
// ... repeat 100,000 lines

という感じでコードを10万行並べる。
*1 *2

手順1

ビルド時間が Xcode のウィンドのタイトルバーに表示される様にしておく。

Terminal で
defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES

手順2

Xcode で
Option+Shift+Command+K で Clean Build Folder を実行

手順3

~Library/Developer/Xcode/DerivedData/ 以下を削除

Terminal で
rm -rdf Library/Developer/Xcode/DerivedData/*

手順4

Xcode で
Command+B でビルドを実行
Destination は iOS Simulator

結果

手順2~4を何回か試したところ以下の結果

コード 時間
cell.accessoryType = UITableViewCell.AccessoryType.checkmark 約90sec
cell.accessoryType = .checkmark 約50sec

意外にも型明記した方が遅かった!
もしかすると型の省略パターンでは左辺により型のツリーの2階層目まで決定していて*3その下の3階層目をチェックするだけのところを、型の明記パターンではまた1階層目から順に型のチェックが走っているという事なのかも知れない。

let a = ... みたいな一般的な変数の型推論パターンでは型指定した方がビルドが早いというのはよく言われる事だけど、今回のケースでは途中まで確定している型を打ち消して記述する事で型チェックの回数が増えてしまい遅くなるという事なんだと思う。

という事で型明記の有無どちらがビルドが早いかはケースバイケースで一概には言えないけど、今回の様な引数やプロパティで型情報が与えられている場合の enum の値の記述については指定の型情報を生かして値だけを書く様にしていこうと思う。

// ex.) 引数
UITableViewCell(style: .default, reuseIdentifier: "Cell")

// ex.) プロパティ
cell.selectionStyle = .blue

*1:やってみた結果1万行じゃ大した差が出なかった

*2:Xcode 上で1万行単位のコピペをやると固まるので TextEdit.app でソースを開いてコピペ作業を行った

*3:これを「推論」というのか単に「型情報が与えられている」というのか