Swift Digest
SE-0545 | Swift Evolution

SwiftPM のビルドパフォーマンスデバッグオプション

SwiftPM Build Performance Debugging Options

Proposal
SE-0545
Authors
Owen Voorhees
Review Manager
Mishal Shah
Status
Active Review (August 12...26, 2026)

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

01 何が問題だったのか

ビルド時間は開発の生産性を大きく左右します。クリーンビルドの速さは、パッケージのビルドにどれだけの作業が必要か、そしてその作業をどれだけ並列化できるかでほぼ決まります。インクリメンタルビルドの速さは、これに加えて、ある変更によってどれだけのビルドが無効化され再実行されるかにも依存します。

ところが、いざパッケージのビルドパフォーマンスを分析しようとすると、ビルドツールやパッケージ構成がこれらの要因にどう影響しているのか、どこに改善の余地があるのかを把握するのは簡単ではありませんでした。ビルド時間を最適化したりパフォーマンス上の問題をデバッグしたりするための情報が乏しく、勘に頼らざるを得ない場面が少なくありませんでした。

02 どのように解決されるのか

SwiftPM に、ビルドパフォーマンスを分析するための2つのコマンドラインオプションを追加します。どちらも swift build / swift test / swift run など、ビルドを実行する任意のサブコマンドに渡せます。

--trace-events-file

--trace-events-file <path> を渡すと、そのビルドで実行された各タスクのタイミングを記述した JSON ファイルが <path> に出力されます。ファイルには、各タスクのコマンドライン、タイミング、(オプションで)バックトレース情報が含まれます。<path> に既存のファイルがある場合、ビルド開始時に上書きされます。

swift build --trace-events-file trace.json

出力形式には、既存の Trace Event Format(JSON ベースのパフォーマンスデータ形式)を採用しています。Clang や Bazel など多くのツールが出力側として、Perfettospeedscope・Chrome の about://tracing などが表示側として対応しているため、出力したトレースをこれらのツールでそのまま可視化できます。

タイムライン表示を使うと、並列度を高めてクリーンビルドを最適化したり、クリティカルパス上にある重い処理を特定したり、ある変更を加えた後のインクリメンタルビルドで実際に走ったタスクの全体像を把握したりするのに役立ちます。

--enable-task-backtraces

トレースを可視化すればインクリメンタルビルドで「どのタスクが走ったか」は分かりますが、「なぜそのタスクが走る必要があったのか」までは分かりません。この疑問に答えるのが task backtrace で、あるタスクが無効化されて再実行されるに至った一連のステップを列挙します。

task backtrace は --enable-task-backtraces を渡すと有効になります。ただし単体では使えず、--trace-events-file(トレースファイルに backtrace 情報を含める)か、--verbose / --very-verbose(ビルド出力に含める)か、その両方と組み合わせる必要があります。ビルドパフォーマンスにわずかながら計測可能な影響があるため、主にインクリメンタルビルドをデバッグするときに使う opt-in の機能として提供されます。

たとえば Basics モジュールの URL.swift を変更した後のインクリメンタルビルドで、swift-build 実行ファイルが再リンクされた理由は次のように表示されます。

#0: an input of 'Link swift-build (arm64)' changed
#1: the task producing file '.../swiftpm/.build/out/Products/Debug/Basics.o' ran
#2: an input of 'Link Basics.o (arm64)' changed
#3: the task producing file '.../swiftpm/.build/out/Intermediates.noindex/SwiftPM.build/Debug/Basics-t.build/Objects-normal/arm64/URL.o' ran
#4: an input of 'Compile Basics (arm64)' changed
#5: file '.../swiftpm/Sources/Basics/URL.swift' changed

最初の行が、そのリンクタスクが走った最も直接的な理由(入力の1つが変わった)を示します。そこから下へ読み進めることで、その変更が元の変更、つまりユーザーによる URL.swift の修正までどうつながっているかをたどれます。この例では、URL.swift の変更により再コンパイルが必要になり、対応するオブジェクトファイルが無効化され、それが Basics ターゲットのリンクを無効化し、さらに最終的な実行ファイルのリンクを無効化した、という連鎖が読み取れます。

入力ファイルの変更以外にも、task backtrace は次のような理由でタスクが再実行されたことを示せます。

  • タスクの引数・作業ディレクトリ・環境変数が変わった
  • タスクの出力の1つがビルド外で削除・変更された
  • 前回のビルドが、そのタスクの実行前に失敗またはキャンセルされた

task backtrace の具体的な書式は実装依存で、将来より詳しい情報を提供できるように柔軟性が残されています。