Swiftのコンパイル時間が非常に遅いのはなぜですか?


209

Xcode 6 Beta 6を使用しています。

これはしばらくの間私を悩ませてきたものですが、それは現在ほとんど使用することができない状態に達しています。

私のプロジェクトは、65個のSwiftファイルといくつかのブリッジされたObjective-Cファイル(まさしく問題の原因ではありません)の適切なサイズになり始めています。

Swiftファイルを少し変更すると(アプリでほとんど使用されないクラスに単純な空白を追加するなど)、指定したターゲットのSwiftファイル全体が再コンパイルされます。

より詳細な調査の結果、コンパイラ時間のほぼ100%を占めているのは、CompileSwiftXcodeがswiftcターゲットのすべてのSwiftファイルに対してコマンドを実行するフェーズであることがわかりました。

さらに調査を行ったところ、アプリデリゲートをデフォルトのコントローラーでのみ維持した場合、コンパイルは非常に高速でしたが、プロジェクトファイルを追加していくと、コンパイル時間が非常に遅くなり始めていました。

現在、ソースファイルは65個しかないため、毎回コンパイルするのに約8/10秒かかります。それほど迅速ではありません。

私は除いて、この問題について話して任意のポスト見ていないこれを、私はその場合には一つだけだ場合、私は思ったんだけどだから、Xcodeの6の古いバージョンでした。

更新

AlitfireEulerCryptoSwiftのようなGitHub上のいくつかのSwiftプロジェクトを確認しましたが、実際に比較するのに十分なSwiftファイルがありませんでした。適切なサイズで開始していることがわかった唯一のプロジェクトはSwiftHNでした。ソースファイルが12個しかなかったとしても、同じことを確認できましたが、1つの単純なスペースとプロジェクト全体で再コンパイルが必要でした。少し時間(2/3秒)。

アナライザーとコンパイルの両方が非常に高速であるObjective-Cコードと比較すると、これはSwiftが大きなプロジェクトを処理することができないように感じますが、私が間違っていると言ってください。

Xcode 6 Beta 7での更新

まだ改善はありません。これはとんでもないことになり始めています。#importSwiftに欠けているので、Appleがこれをどのように最適化できるかは本当にわかりません。

Xcode 6.3およびSwift 1.2での更新

Appleはインクリメンタルビルド(および他の多くのコンパイラ最適化)を追加しました。これらの利点を確認するには、コードをSwift 1.2に移行する必要がありますが、AppleはXcode 6.3にそのためのツールを追加しました。

ここに画像の説明を入力してください

しかしながら

私のようにあまり早く喜んではいけません。ビルドをインクリメンタルにするために使用するグラフソルバーは、まだ十分に最適化されていません。

実際、最初に、関数のシグネチャの変更は確認されないため、1つのメソッドのブロックにスペースを追加すると、そのクラスに依存するすべてのファイルが再コンパイルされます。

第二に、変更がそれらに影響を与えない場合でも、再コンパイルされたファイルに基づいてツリーを作成するようです。たとえば、これらの3つのクラスを別のファイルに移動した場合

class FileA: NSObject {
    var foo:String?
}
class FileB: NSObject {
    var bar:FileA?
}
class FileC: NSObject {
    var baz:FileB?
}

これで、を変更するFileAと、コンパイラーは明らかFileAに再コンパイルするようにマークします。また、再コンパイルしますFileB(それはへの変更に基づいてOKでしょうFileA)、しかしまたFileCのでFileB、再コンパイル、およびされているので、それはかなり悪いですFileC決してを使用していないFileAここに。

依存関係ツリーソルバーが改善されることを願っています... このサンプルコードでレーダーを開きました。

Xcode 7ベータ5およびSwift 2.0での更新

昨日Appleがベータ5をリリースし、リリースノートの中に次のように表示されました。

Swift言語とコンパイラ•インクリメンタルビルド:関数の本体のみを変更しても、依存ファイルが再ビルドされなくなりました。(15352929)

私はそれを試してみましたが、今は本当に(本当に!)うまく機能していると言わなければなりません。彼らは迅速にインクリメンタルビルドを最適化しました。

swift2.0XCode 7ベータ5を使用して、ブランチを作成し、コードを最新の状態に保つことを強くお勧めします(コンパイラーの機能強化に満足します(ただし、XCode 7のグローバルな状態はまだ遅く、バグが多いと思います)。

Xcode 8.2での更新

この問題に関する私の最後の更新からしばらく経ちましたので、ここにあります。

私たちのアプリは現在、ほぼ独占的にSwiftコードの約20k行です。Swift 2とSwift 3よりも移行が進んだ。2014年半ばのMacbook pro(2.5 GHz Intel Core i7)でコンパイルするには約5/6分かかりますが、クリーンビルドでは問題ありません。

ただし、アップルが次のように主張しているにもかかわらず、インクリメンタルビルドはまだ冗談です。

小さな変更のみが発生した場合、Xcodeはターゲット全体を再構築しません。(28892475)

明らかに、私はこのナンセンスをチェックした後、私たちの多くが笑っただけだと思います(プロジェクトのファイルにプライベート(プライベート!)プロパティを1つ追加すると、すべてが再コンパイルされます...)

私はあなたに問題についていくつかのより多くの情報を持っているApple開発者フォーラムのこのスレッドをあなたに指摘したいと思います(そして時々問題に関するApple開発者のコ​​ミュニケーションに感謝します)

基本的に、人々はインクリメンタルビルドを改善するためにいくつかのことを考え出しました:

  1. HEADER_MAP_USES_VFSプロジェクト設定セットを追加true
  2. Find implicit dependenciesスキームから無効にする
  3. 新しいプロジェクトを作成し、ファイル階層を新しいプロジェクトに移動します。

ソリューション3を試してみますが、ソリューション1/2は機能しませんでした。

この全体的な状況で皮肉なことに面白いのは、この問題の最初の投稿を見て、最初のコンパイルが遅くなったときにSwift 1またはSwift 1.1のコードでXcode 6を使用していたことです。 Xcode 6の場合と同じように状況は悪いです。

私は実際には本当にためにそれが必要とする毎日欲求不満の私たちのプロジェクトのためのObj / C上スウィフトを選ぶ後悔します。(私もAppCodeに切り替えますが、それは別の話です)

とにかく、このSOの投稿には、この記事の執筆時点で32k以上のビューと143のアップがあることがわかります。この状況に悲観的であるにもかかわらず、トンネルの端に若干の光があるかもしれません。

時間があれば(そして勇気も!)、Appleはこれに関するレーダーを歓迎すると思います。

次回まで!乾杯

Xcode 9での更新

今日これにつまずく。Xcodeは静かに新しいビルドシステムを導入し、現在のひどいパフォーマンスを改善しました。ワークスペースの設定で有効にする必要があります。

ここに画像の説明を入力してください

まだ試してみましたが、完了したらこの投稿を更新します。有望に見えますが。


1
面白い!インターフェイスファイルがないため、最適化が欠けているのか、それとも多くのファイルを解析する必要があるのか​​と思います。
zaph 2014

2
同様の問題があり、最終的には、JSONから逆シリアル化するためにエンティティークラスで使用されるカスタム演算子が原因であることに気付きました。いずれかを使用している場合は、通常の関数に1つずつ変換してみて、何か変更があるかどうかを確認することをお勧めします。
アントニオ

4
XCode 6ベータ6以降、私のプロジェクトではコンパイルが非常に遅くなりました。ベータ版の変更が原因か、コードが原因かはわかりません。しかし、私のプロジェクトはまだ大きくはありません(40〜50のSwiftファイル)。
BadmintonCat

2
プロジェクトが成長するにつれて、コンパイルは耐えられないほど遅くなります。私はいくつかのポッドにも依存していますが、それによって問題がさらに悪化することは間違いありません。これは最近の非ベータリリースを使用しています。
アンディ

2
インクリメンタルビルドは「保守的な依存関係の分析」で行われるため、絶対に必要なファイルよりも多くのファイルが再ビルドされる場合があります。うまくいけば、それは時間とともに改善するでしょう。
nmdias

回答:


70

まあ、それはロブネイピアが正しかったことがわかりました。コンパイラがberzekする原因となったのは、1つのファイル(実際には1つの方法)でした。

誤解しないでください。Swiftは毎回すべてのファイルを再コンパイルしますが、素晴らしいのは、Appleがコンパイルするファイルにリアルタイムのコンパイルフィードバックを追加したことです。これにより、Xcode 6 GMは、コンパイルされているSwiftファイルとコンパイルのステータスをリアルタイムで表示します。このスクリーンショットでわかるように:

ここに画像の説明を入力してください

したがって、どのファイルに時間がかかっているかを知るのに非常に便利です。私の場合、それはこのコードの一部でした:

var dic = super.json().mutableCopy() as NSMutableDictionary
dic.addEntriesFromDictionary([
        "url" : self.url?.absoluteString ?? "",
        "title" : self.title ?? ""
        ])

return dic.copy() as NSDictionary

プロパティtitleはタイプvar title:String?ではなくタイプだったためNSStringです。コンパイラをに追加すると、おかしくなりましたNSMutableDictionary

それを次のように変更します。

var dic = super.json().mutableCopy() as NSMutableDictionary
dic.addEntriesFromDictionary([
        "url" : self.url?.absoluteString ?? "",
        "title" : NSString(string: self.title ?? "")
        ])

return dic.copy() as NSDictionary

コンパイルを10/15秒(たぶんそれ以上)から1秒に短縮しました...すごい。


3
回答をフォローしていただきありがとうございます。これは、コンパイル中に型推論エンジンが行き詰まる他のユーザーにとって非常に役立つ場合があります。
Rob Napier

1
どこでこのビュー@apoucheに行きましたか?xcodeに表示されません
Eric

2
デバッグアシスタント(CMD + 8)を開き、現在のビルドをクリックする必要があります
apouche

1
ええ、私はAppleが後でこれを最適化すると確信しています。
apouche 2014

1
どのファイルがコンパイルされているかを示すこのツールにどのようにアクセスできますか?
jgvb

41

約100k行のSwiftコードと300k行のObjCコードがあるので、これに対処するためにいくつかのことを試みました。

最初のステップは、関数のコンパイル時間の出力に従ってすべての関数を最適化することでした(例:https://thatthinginswift.com/debug-long-compile-times-swift/)。

次に、すべてのSwiftファイルを1つのファイルにマージするスクリプトを作成しました。これにより、アクセスレベルが低下しますが、コンパイル時間が5〜6分から1分に短縮されました。

Appleにこれについて尋ねたところ、次のようにするように助言されたため、これは現在は機能していません。

  1. 「Swiftコンパイラ-コード生成」ビルド設定で「モジュール全体の最適化」をオンにします。選択する'Fast, Whole Module Optimization'

ここに画像の説明を入力してください

  1. 'Swift Compiler-Custom Flags'に、開発ビルド用に次を追加します '-Onone'

ここに画像の説明を入力してください ここに画像の説明を入力してください

これらのフラグが設定されている場合、コンパイラーはすべてのSwiftファイルを1つのステップでコンパイルします。マージスクリプトを使用すると、ファイルを個別にコンパイルするよりもはるかに高速です。ただし、-Onone'オーバーライドを行わないと、モジュール全体が最適化され、速度が低下します。設定すると'-Onone'他のSwiftフラグにフラグすると、最適化は停止しますが、すべてのSwiftファイルのコンパイルが1ステップで停止するわけではありません。

モジュール全体の最適化の詳細については、こちらのAppleのブログ投稿をご覧ください- https://swift.org/blog/whole-module-optimizations/)をご覧ください。

これらの設定により、Swiftコードを30秒でコンパイルできることがわかりました。

App Storeのビルド'-Onone'については、本番ビルドでは最適化が推奨されるため、フラグは省略してください。


4
このアドバイスをどうもありがとう!公式の情報源にそのようなものが何もない理由を理解していません(少なくとも見つけるのは簡単です)-Onone。コンパイラーがクラッシュするため、現時点ではモジュール全体の最適化を使用できません...しかし、あなたのアドバイスにより、ビルド速度がほぼx10向上します。MacBook Air(毎年2013年)では、約8分でビルドされていましたが、ターゲットの切り替え(アプリ、拡張機能、いくつかの社内フレームワークがあります)とストーリーボードのコンパイルにかかる時間の約1分半になりました
Ilya Puchka

私はこの方法もテストしましたが、これは-Ononeを含む唯一の方法であり、ビルド時間を大幅に短縮します。
Vlad

私も一緒に働いてください。-Ononeビルド時間を短縮するためのヘルプの使用。たくさんの仲間に感謝します!
nahung89 2017

34

プロジェクトのサイズとはほとんど関係ありません。それはおそらく特定のコードの断片であり、たぶん1行でさえあります。プロジェクト全体ではなく、一度に1つのファイルをコンパイルすることで、これをテストできます。または、ビルドログを見て、どのファイルに時間がかかっているかを確認してください。

問題を引き起こす可能性のあるコードの種類の例として、この38行の要点は、beta7でコンパイルするのに1分以上かかります。それはすべて、この1つのブロックが原因です。

let pipeResult =
seq |> filter~~ { $0 % 2 == 0 }
  |> sorted~~ { $1 < $0 }
  |> map~~ { $0.description }
  |> joinedWithCommas

ほんの1、2行で単純化すれば、ほとんど瞬時にコンパイルされます。問題は、コンパイラの指数関数的成長(おそらく階乗的成長)を引き起こしていることです。明らかにそれは理想的ではなく、そのような状況を分離できる場合は、レーダーを開いてこれらの問題を解決する必要があります。


CompileSwiftフェーズに関する私のコメントを見たのかわかりません。変更されたファイルが1つだけであっても、すべての迅速なファイルを取得します。したがって、時間がかかるのが1つのファイルである場合(これは非常に疑わしいです)、コンパイラーはそれがどれであるかを通知しません。
apouche 2014

10
を使用swiftcして個々のファイルをコンパイルし、それらにかかる時間を確認できます。
Rob Napier

最初はそれを信じられないので、あなたに賞金を与えなかったことをお詫びします。私もファイルを1つずつコンパイルしようとしましたが、やるのが面倒だった(適切にフレームワークを提供しなければならず、毎回depsする必要があった)ので、あきらめました。詳細については、この投稿に対する最新の回答を参照してください
apouche

プロジェクトの規模に基づいているとは思いません。私のプロジェクトには4つの高速ファイルしかないため、突然コンパイルが非常に遅くなりました。昨日はあっという間でした。アイコンの追加と画像の起動を除いて、特にプロジェクトに対して行った操作に指をかけることができません。
Travis M.

33

コンパイル時間を遅くする特定のファイルを識別しようとしている場合は、xctoolを使用してコマンドラインからコンパイルし、ファイルごとにコンパイル時間を取得できます。

注意すべきことは、デフォルトでは、各CPUコアごとに2つのファイルを同時にビルドし、「正味」経過時間ではなく、絶対「ユーザー」時間を提供することです。この方法では、並列化されたファイル間ですべてのタイミングが均一になり、非常によく似ています。

これを克服するには、-jobsフラグを1に設定して、ファイルのビルドが並列化されないようにします。時間がかかりますが、最終的にはファイルごとに比較できる「ネット」コンパイル時間になります。

これは、トリックを実行する必要があるコマンドの例です。

xctool -workspace <your_workspace> -scheme <your_scheme> -jobs 1 build

「Swiftファイルのコンパイル」フェーズの出力は次のようになります。

...Compile EntityObserver.swift (1623 ms)Compile Session.swift (1526 ms)Compile SearchComposer.swift (1556 ms)
...

この出力から、コンパイルに他のファイルより時間がかかっているファイルをすばやく特定できます。さらに、リファクタリング(明示的なキャスト、型ヒントなど)が特定のファイルのコンパイル時間を短縮しているかどうかを高精度で判断できます。

注:技術的にはこれを使用することもできますxcodebuildが、出力は非常に冗長であり、消費するのが困難です。


1
プロジェクトのWhole Module Optimizationがfalseに設定されていることを確認してください。そうしないと、個々のSwiftファイルが分離されません。
sabes

1
参照Swift CompilerOptimization LevelのためにFast, Whole Module Optimization [-O -whole-module-optimization]
マット

26

私の場合、Xcode 7はまったく違いがありませんでした。コンパイルに数秒かかる複数の機能がありました。

// Build time: 5238.3ms
return CGSize(width: size.width + (rightView?.bounds.width ?? 0) + (leftView?.bounds.width ?? 0) + 22, height: bounds.height)

オプションをアンラップした後、ビルド時間は99.4%減少しました

// Build time: 32.4ms
var padding: CGFloat = 22
if let rightView = rightView {
    padding += rightView.bounds.width
}

if let leftView = leftView {
    padding += leftView.bounds.width
}
return CGSizeMake(size.width + padding, bounds.height)

この投稿この投稿で他の例をご覧ください。

Xcode用のTime Analyzerをビルドする

これらの問題が発生している人にとって便利なXcodeプラグイン開発しました。

画像

Swift 3には改善点があるようで、Swiftコードがより速くコンパイルされることを期待しています。


すばらしいです。+ 1以上を差し上げます。あなたは本当であり、あなたのプラグインも素晴らしいです。私はそれを使用していて、ビルド時間が短縮されています。これは、このオプションが悪夢であり、コンパイラーの速度を低下させる原因となるため、超高速開発を意味します。
hardikdevios

素晴らしい!あなたのツールは私を大いに助けてくれます。ありがとう
Phil

素晴らしいプラグイン-本当に便利です!ありがとう
365SplendidSuns 2016

@Robert Gummesson、Objective-Cコード用のツールはありますか?
アショク

19

おそらくSwiftコンパイラーは修正できませんが、修正できるのはコードです。

Swiftコンパイラには隠しオプションがあり、コンパイラがすべての関数をコンパイルするのにかかる正確な時間間隔を出力します-Xfrontend -debug-time-function-bodies。これにより、コードのボトルネックを見つけ、コンパイル時間を大幅に改善できます。

ターミナルで以下を実行し、結果を分析します。

xcodebuild -workspace App.xcworkspace -scheme App clean build OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" | grep [1-9].[0-9]ms | sort -nr > culprits.txt

素晴らしいブライアンイレースは、Swiftのコンパイル時間のプロファイリングについて素晴らしい記事を書いています


2
alias grep='noglob grep'最初にzshを使用している場合、othewise grepは機能しません
Jaime Agudo

16

解決策はキャストです。

次のような膨大な数の辞書がありました。

["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
["title" : "someTitle", "textFile" : "someTextFile"],
.....

コンパイルには約40分かかりました。私がこのような辞書をキャストするまで:

["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
["title" : "someTitle", "textFile" : "someTextFile"] as [String : String],
....

これは、アプリケーションにハードコーディングしたデータ型に関して私が遭遇した他のほぼすべての問題に役立ちました。


6
はい、それはコンパイル時間を改善するために行う最適化の一部ですが、現在のSwiftコンパイラの主な問題は、わずかな変更を加えるたびにすべてのSwiftファイルを再コンパイルすることです。
apouche 2015

4
それがそれほど悲しくなければ、それはおかしいでしょう。
トムアンデルセン

15

注意すべき点の1つは、入れ子になった型を使用すると、Swiftの型推論エンジンが非常に遅くなる可能性があることです。時間がかかる個々のコンパイルユニットのビルドログを監視し、Xcodeで生成されたコマンド全体をターミナルウィンドウにコピーして貼り付け、CTRL- \を押して、スローが発生している原因についての一般的なアイデアを得ることができます。いくつかの診断。完全な例については、http://blog.impathic.com/post/99647568844/debugging-slow-swift-compile-timesご覧ください。


それが私にとって最良の答えです(リンクを参照)。問題だった2つの異なる行を簡単に見つけ、行をより小さな行に分解することで解決できました。
ニコ

これは、コンパイラがおかしくなった場所を見つける方法を示しているので、非常に役立つ回答です。私の場合、それは次のとおりでした: 'curScore [curPlayer%2] + curScore [2 + curPlayer%2] == 3 && maker%2 == curPlayer%2'「if」から「let」に移動するとすぐ'、「式が複雑すぎて妥当な時間内に解決できないため、式を個別の部分式に分解することを検討してください」
Dmitry

これは間違いなくこの問題を解決するための最も役立つ方法です。
Richard Venable、2015年

9

また、デバッグ用にコンパイルするときは(SwiftまたはObjective-C)、[アクティブアーキテクチャのみをビルド]に設定していることを確認してください。

ここに画像の説明を入力してください


6

これらはすべてベータ版であり、Swiftコンパイラーは(少なくとも現在のところ)オープンではないため、質問に対する実際の答えはないと思います。

まず、Objective-CとSwiftコンパイラを比較することは、何となく残酷です。Swiftはまだベータ版で、Appleは機能の提供とバグの修正に取り組んでいると思います。電光石火の速度を提供するだけではありません(家具を購入して家を建て始めるのではありません)。アップルはやがてコンパイラを最適化するでしょう。

何らかの理由ですべてのソースファイルを完全にコンパイルする必要がある場合、個別のモジュール/ライブラリを作成するオプションが考えられます。しかし、Swiftは言語が安定するまでライブラリを許可できないため、このオプションはまだ使用できません。

彼らはコンパイラを最適化すると思います。プリコンパイル済みモジュールを作成できないのと同じ理由で、コンパイラーがすべてを最初からコンパイルする必要がある場合もあります。しかし、言語が安定したバージョンに達し、バイナリの形式が変更されなくなったら、ライブラリを作成できるようになり、コンパイラー(?)もその作業を最適化できるようになります。

ただ推測するだけです、なぜならAppleだけが知っているからです...


「プリコンパイル済みモジュールを作成できないのと同じ理由で、コンパイラーがすべてを最初からコンパイルする必要がある場合もあります。」すばらしい観察です。以前はそう考えていませんでした。
chakrit 2015

1
2017年、それでもまだ遅い
ペドロパウロアモリム

2017年Xcode 9と新しいビルドシステムを使用してもまだ遅い
pableiros

Xcode 9を使用した2018年、50以上の迅速なファイルを含むプロジェクトがあります。クリーンビルドを実行すると、5分経過し、コンパイルはまだ完了していません。
Chen Li Yong

5

Xcode 8の場合は、プロジェクト設定に移動し、[エディター]> [ビルド設定の追加]> [ユーザー定義設定の追加]に移動して、以下を追加します。

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

このフラグを追加すると、40KLOCの迅速なプロジェクトのクリーンビルドのコンパイル時間が7分から65秒に奇跡的に減少しました。また、2人の友人がエンタープライズプロジェクトで同様の改善を見たことが確認できます。

私はこれがXcode 8.0のある種のバグであるとしか想定できません

編集:それは一部の人々のためにXcode 8.3でもう機能しないようです。


2
「プロジェクト設定」はどこにありますか?
Raniys、2016年

@Raniys Xcodeの左ペインのルートレベルにある青いアイコンをクリックします。
Chris

Xcode 8.3(非ベータ版)以降、これは私の場合機能しなくなります:(
Chris

4

残念ながら、Swiftコンパイラはまだ高速でインクリメンタルなコンパイル用に最適化されていません(Xcode 6.3ベータ以降)。一方、Swiftのコンパイル時間を改善するために、次のテクニックのいくつかを使用できます。

  • アプリをフレームワークに分割して、再コンパイルの影響を減らします。ただし、アプリで循環依存関係を回避する必要があることに注意してください。このトピックの詳細については、この投稿を確認してください:http ://bits.citrusbyte.com/improving-swift-compile-time/

  • プロジェクトの非常に安定していて頻繁に変更されない部分にSwiftを使用します。頻繁に変更する必要がある他の領域や、完了するために多くのコンパイル/実行の反復が必要な領域(ほとんどすべてのUI関連のもの)については、Objective-Cを組み合わせて使用​​する方が適切です。

  • 「Xcodeのインジェクション」でランタイムコードインジェクションを試す

  • roopcメソッドを使用:http ://roopc.net/posts/2014/speeding-up-swift-builds/

  • 明示的なキャストでいくつかのヒントを与えることにより、迅速な型推論エンジンを緩和します。


4

Swiftの配列と辞書の構築は、これのかなり一般的な原因のようです(特に、Rubyのバックグラウンドを持っている人にとって)。

var a = ["a": "b",
         "c": "d",
         "e": "f",
         "g": "h",
         "i": "j",
         "k": "l",
         "m": "n",
         "o": "p",
         "q": "r",
         "s": "t",
         "u": "v",
         "x": "z"]

おそらくこれがそれを修正するべき原因です:

var a = NSMutableDictionary()
a["a"] = "b"
a["c"] = "d"
... and so on

4

デバッグとテストの場合は、次の設定を使用して、コンパイル時間を約20分から2分未満に削減してください。

  1. プロジェクトのビルド設定で、「最適化」を検索し、デバッグを「最高速[-O3]」以上にします。
  2. アクティブアーキテクチャのビルドを設定:はい
  3. デバッグ情報フォ​​ーマット:DWARF
  4. モジュール全体の最適化:いいえ

私は、プロジェクトがビルドされるのを待つために数え切れないほどの時間を無駄にしました。それは、1つの小さな変更を行う必要があり、それをテストするためにさらに30分間待つ必要があったことを認識しただけです。これらは私のために働いた設定です。(私はまだ設定を試しています)

ただし、少なくとも "DWARF with dSYM"を設定し(アプリケーションを監視する場合)、ビルド/アクティブアーキテクチャを "NO"に設定して、リリース/アーカイブでiTunes Connectにプッシュするようにしてください(ここでも数時間を無駄にしたことを覚えています)。


4
私は間違っているかもしれませんが、最適化レベルを高く設定すると、実際にビルド時間が長くなりますか?最適化レベルにより、実行時のパフォーマンスが向上します。
マイケルウォーターフォール

1
Set Build for Active Architecture: YESコンパイル時間を約45%短縮できました。本当にありがとう。
Jean Le Moignan、2015年

4

コンパイラーは、型の推測とチェックに多くの時間を費やしています。したがって、型注釈を追加することで、コンパイラが非常に役立ちます。

あなたのような連鎖関数呼び出しがたくさんある場合

let sum = [1,2,3].map({String($0)}).flatMap({Float($0)}).reduce(0, combine: +)

次に、コンパイラーはタイプがsumどうあるべきかを理解するのにしばらく時間がかかります。タイプを追加すると役立ちます。また、断続的なステップを別々の変数にまとめることも役立ちます。

let numbers: [Int] = [1,2,3]
let strings: [String] = sum.map({String($0)})
let floats: [Float] = strings.flatMap({Float($0)})
let sum: Float = floats.reduce(0, combine: +)

特に数値型のCGFloat場合、Int非常に役立ちます。のようなリテラル数2は、多くの異なる数値タイプを表すことができます。したがって、コンパイラーはコンテキストからそれがどれであるかを理解する必要があります。

検索に時間がかかる関数+も避けてください。+複数の配列を連結するためにいくつかを使用すると、コンパイラーがそれぞれに対してどの実装を+呼び出す必要があるかを把握する必要があるため、処理が遅くなります+。したがって、可能であれば代わりにvar a: [Foo]with append()を使用してください。

Xcodeでのコンパイルが遅い関数を検出する警告を追加できます。

ではビルド設定のためのあなたのターゲット検索の他スウィフトフラグとアドオン

-Xfrontend -warn-long-function-bodies=100

コンパイルに100ミリ秒以上かかるすべての関数について警告します。


4

Objective-Cのとスウィフトコードを混在プロジェクトでは、我々は、設定することができます-enable-bridging-pchOther Swift Flags。これにより、ブリッジングヘッダーは1回だけ解析され、結果(一時的な「プリコンパイル済みヘッダー」または「PCH」ファイル)がキャッシュされ、ターゲット内のすべてのSwiftファイルで再利用されます。Appleはビルド時間を30%短縮したと主張している。参照リンク:

注:これはSwift 3.1以降でのみ機能します。


2

私のMacを再起動すると、この問題は不思議でした。再起動するだけで、15分ビルドから30秒ビルドになりました。


1

新しいXcode 6.3では、 Swiftのコンパイル時間が改善されました

コンパイラーの改善

Swift 1.2コンパイラは、より安定し、あらゆる点でパフォーマンスを向上させるように設計されています。これらの変更により、XcodeでSwiftを操作する際のエクスペリエンスも向上します。最も目に見える改善のいくつかは次のとおりです。

インクリメンタルビルド

変更されていないソースファイルはデフォルトで再コンパイルされなくなり、ほとんどの一般的なケースでビルド時間が大幅に改善されます。コードの構造的変更が大きい場合でも、複数のファイルを再構築する必要があります。

より高速な実行可能ファイル

デバッグビルドは、かなり高速に実行されるバイナリを生成し、新しい最適化により、リリースビルドのパフォーマンスがさらに向上します。

より良いコンパイラ診断

エラーメッセージと警告メッセージがより明確になり、新しいFix-itsにより、適切なSwift 1.2コードを簡単に記述できます。

安定性の向上

最も一般的なコンパイラのクラッシュが修正されました。Xcodeエディター内に表示されるSourceKit警告も少なくなります。


0

これは、型推論で大幅な速度低下を引き起こす可能性がある別のケースです。合体演算子

次のような行の変更:

abs(some_optional_variable ?? 0)

abs((some_optional_variable ?? 0) as VARIABLE_TYPE)

コンパイル時間を70年代から13年代に引き上げるのに役立ちました


0

Xcode 6.3.1では何も機能しませんでした-約100のSwiftファイルを追加すると、Xcodeはビルドやインデックス作成でランダムにハングしました。モジュラーオプションを試しましたが、成功しませんでした。

Xcode 6.4 Betaのインストールと使用が実際に機能しました。


0

これは私にとって魔法のように機能しています-Speed Up Swift Compilation。コンパイル時間が10分から3分に短縮されました。

それはあなたがオンにする必要があり言いWhole Module Optimization加えながら-OnoneOther Swift Flags

/を使用Swift 3していXcode 8.3Xcode 8.2ます。


0

1つの式に整数リテラルと浮動リテラルを混在させると、コンパイル時間が長くなります。

1.0 + (1.0 + (1  * (1.0 + 1.0))) // 3429ms

1.0 + (1.0 + (1.0  * (1.0 + 1.0))) // 5ms

多くの1000 + msコンパイル時の式は、.0後整数リテラルを置いた後、10〜100msに短縮されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.