Swift Digest
Blog | Swift.org Blog

Swift 4.1 のコードサイズ最適化モード

Code Size Optimization Mode in Swift 4.1

このダイジェストはClaude Opus 4.7 / 4.8によって生成されたものです(License)。原文はこちら

この記事の要点

背景: 最適化とコードサイズのトレードオフ

Swift コンパイラは強力な最適化を備えており、-O を指定すると最大限の実行性能を引き出すようにコードを変換します。しかし、この実行性能の向上は、しばしば コードサイズの増加 とのトレードオフになります。

-Osize モードは、この選択肢を利用者に与えるものです。最大速度ではなく最小のコードサイズを優先してコンパイルしたい場合に、-O の代わりに -Osize を使います。

コード最適化への影響

-Osize でも、コンパイラは -O と同じようにコードを最適化します。違いは、-Osize ではコンパイラが コードの重複を避けようとする 点です。

インライン化のサイズ上限を下げる

たとえば関数のインライン化(inlining)では、-Osize はある関数をインライン化すべきか判断するためのサイズ上限を低く設定します。

ただし、インライン化を完全に無効化するのは得策ではありません。小さな関数のインライン化は、むしろコードサイズの削減につながることが多いからです。たとえば次のような単純な getter を考えます。

struct X {
    var x: Int { return 27 }
}

この getter を呼び出すための呼び出しオーバーヘッドは、関数をインライン化する場合より大きくなります。これは極端な例ですが、ある程度のサイズまではインライン化がコードサイズの改善に寄与します。

さらに、インライン化は別の最適化を誘発し、その結果コードサイズを減らせることもあります。次の例では、getter a.x をインライン化すると a.x が 27 に評価されると分かるため、if ブランチ全体を取り除けます。

func foo(a: X) {
    if a.x != 27 {
        // Can be optimized away if the getter of a.x is inlined
    }
}

ヘルパー関数への抽出

インライン化以外にも、-Osize はコードサイズに特化した最適化を行います。たとえば、ジェネリック型の処理や Objective-C bridging のための一部のコードパターンを、インラインで生成せずにヘルパー関数として抽出します。これによって同じパターンの重複を避けます。

まとめ

-Osize モードは、極端に性能が重視されるわけではないプログラムのコードサイズを削減する有効な手段です。当時の記事は試用とフィードバックを呼びかけており、フォーラムでは osize タグで体験を共有するよう案内していました。

関連リンク