web-dev-qa-db-ja.com

Xcode 8は非常に遅いSwiftコンパイル

Swift 3およびXcode 8以来、プロジェクトのコンパイルは非常に遅くなります。ファイルに空の行を追加するたびに、再コンパイルに1分かかります。出力を確認すると、非常に長い時間がかかる特定のファイルはありません(このツールを使用して測定しました: https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode

一度に4つのファイルをコンパイルするように常に見えます。 「リズム」は非常に安定しています。ただ非常に遅い...

また、ファイルを開いたり、ファイルを切り替えたりするたびに、オートコンプリートまたはエラー/警告が表示されるまで非常に時間がかかる場合があります。

何を確認できますか?ビルド速度を狂わせるようにドラッグダウンするフラグが設定されているように感じます。

EDIT:これは根本的な問題の解決策ではありませんが、より多くのコードをフレームワークに移動することに時間を費やしました。これにより違いが生じました(毎回より少ないファイルを再コンパイルする必要があるためです)。これは必要ではありませんが、耐え難いものになりました...私はもちろん、適切な解決策を非常に探しています。

36
fancy

この問題の問題は、間違った初期化/宣言がどこにあるかわからないことです。私の同僚が提案する解決策は、どの関数をコンパイルするのに時間がかかるかを見つけることです:

  1. Projectに移動してターゲットを選択します
  2. Build Settings-> Swift Compiler - Custom Flags
  3. 追加 Other Swift Flags-Xfrontend -warn-long-function-bodies=50(50はミリ秒単位の時間を表します)

その後、次のように警告が表示されます。

ゲッター 'frameDescription'は型チェックに108msかかりました(制限:50ms)

そしてその後、あなたは何をすべきかを知っています;)

26

Swift 3/XCode 8にアップグレードしてから同じ問題が発生しました。これは this と同様に大きな配列リテラルが原因であるようです。

配列リテラルに割り当てられている変数に型注釈を追加することで問題を修正できました。

let array: Array<String> = ["1", "2", "3", "4", "5", "6", "7", "8"]

の代わりに

let array = ["1", "2", "3", "4", "5", "6", "7", "8"]
5
Ben Simon

これは、増分ビルドが正しく実行されないXcode 8の問題です。単一のSwiftファイルを編集する場合は、そのファイルのみをコンパイルする必要があります。これは既にここで発生しています: Xcode 8は完全なプロジェクトの再構築

一度に4つのファイルをビルドすると、Xcodeがプロジェクトの完全な再構築を実行しているように聞こえます。

5
Vlad

私の場合、ヘルパー関数を使用して一部のデータをFirebaseに保存していました。その関数は約20の要素を持つ辞書を返していましたが、コンパイルには約40分かかりました。私の解決策は、空の辞書を初期化してから、アイテムを1つずつsomeDictに追加することでした。現在、30秒未満でコンパイルされます。役に立てば幸いです。

func toAnyObject() -> AnyObject {
  return
      ["BookingAmount":BookingAmount,
     "BookingNumber":BookingNumber,
     "PostCode":PostCode,
     "SelectedBathRow":SelectedBathRow,
     "SelectedBedRow":SelectedBedRow,
     "DateAndTime":DateAndTime,
     "TimeStampDateAndTime":TimeStampDateAndTime,
     "TimeStampBookingSavedInDB": TimeStampBookingSavedInDB,
     "FrequencyName":FrequencyName,
     "FrequecyAmount":FrequecyAmount,
     "insideCabinets": insideCabinets,
     "insideFridge": insideFridge,
     "insideOven": insideOven,
     "laundryWash": laundryWash,
     "interiorWindows": interiorWindows,
     "FullName":FullName,
     "SuppliesName":SuppliesName,
     "SuppliesAmount":SuppliesAmount,
     "FlatNumber":FlatNumber,
     "StreetAddress":StreetAddress,
     "PhoneNumber":PhoneNumber,
     "EmailAddress":EmailAddress] as AnyObject

}

  func toAnyObject() -> AnyObject {

    var someDict = [String : AnyObject]()
    someDict["BookingAmount"] = self.BookingAmount as AnyObject?
    someDict["BookingNumber"] = self.BookingNumber as AnyObject?
    someDict["PostCode"] = self.PostCode as AnyObject?
    someDict["SelectedBathRow"] = self.SelectedBathRow as AnyObject?
    someDict["SelectedBedRow"] = self.SelectedBedRow as AnyObject?
    someDict["DateAndTime"] = self.DateAndTime as AnyObject?
    someDict["TimeStampDateAndTime"] = self.TimeStampDateAndTime as AnyObject?
    someDict["TimeStampBookingSavedInDB"] = self.TimeStampBookingSavedInDB as AnyObject?
    someDict["FrequencyName"] = self.FrequencyName as AnyObject?
    someDict["FrequecyAmount"] = self.FrequecyAmount as AnyObject?
    someDict["insideCabinets"] = self.insideCabinets as AnyObject?
    someDict["insideFridge"] = self.insideFridge as AnyObject?
    someDict["insideOven"] = self.insideOven  as AnyObject?
    someDict["laundryWash"] = self.laundryWash as AnyObject?
    someDict["interiorWindows"] = self.interiorWindows as AnyObject?
    someDict["FullName"] = self.FullName as AnyObject?
    someDict["SuppliesName"] = self.SuppliesName as AnyObject?
    someDict["SuppliesAmount"] = self.SuppliesAmount as AnyObject?
    someDict["FlatNumber"] = self.FlatNumber as AnyObject?
    someDict["StreetAddress"] = self.StreetAddress as AnyObject?
    someDict["PhoneNumber"] = self.PhoneNumber as AnyObject?
    someDict["EmailAddress"] = self.EmailAddress as AnyObject?

    return someDict as AnyObject
}
3
bibscy

Nil-Coalescing Operatorと文字列連結の使用を回避することで、プロジェクトのコンパイル時間を大幅に短縮できましたSwift=.

言い換えれば、私は次のようなものを持っていました:

let x = "one" + object.nullableProperty ?? ""

に変更しました

let x = String(format: "one %@", object.nullableProperty ?? "")

コンパイル時間が20分から20秒に大幅に短縮されました。

1
Logan Sease

これは私のプロジェクトの1つでうまくいきました。

[製品]-> [スキーム]-> [スキームの編集]に移動します。左側の列で[ビルド]を選択し、[暗黙的な依存関係を見つける]のチェックを外しますが、プロジェクトを初めてビルドするときは、このフラグはチェックしたままにしてください。

ソース

これは単純なプロジェクトで、ビルドの1つを1分から2秒に増やしました。

物理デバイスでこれらの結果を得ました。私の大きなプロジェクト(42ファイル)の1つでは、2:36から2:20にしか減少しませんでした。次に、ユーザー定義の設定としてビルド設定にSwift_WHOLE_MODULE_OPTIMIZATION = YESを追加しました。時間が下がった-2:00

シミュレータでは、初めて使用したときのビルドは49秒でした。

[製品]-> [スキーム]-> [スキームの編集]に移動します。左側の列で[ビルド]を選択し、[暗黙的な依存関係を見つける]のチェックを外しますが、プロジェクトを初めてビルドするときは、このフラグはチェックしたままにしてください。

ビルドには7秒かかりました。

これがお役に立てば幸いです。

1
uplearnedu.com

_let combinedArrays = array1 + array2_のような配列を組み合わせていないことを確認してください。ここには型推論の既知のバグもありますが、ここでSwift=はcombinedArraysがどの型であるかを理解しようとして時間を浪費します。代わりに、[array1, array2].joined()は同様に動作し、はるかに高速にコンパイルします。

0
Dylan Gattey

コンパイル時間を遅くする一般的な方法の1つは、Array.appendおよびString.append(またはその+演算子に相当)。 Stringsの場合、フォーマットされた文字列を使用する方が良いため、代わりに

let hello = "Hello, "
let world = "World!"
let combinedString = hello + world

あなたは使うべきです

let combinedString = "\(hello)\(world)"

正確なスピードアップを思い出すことはできませんが、それらの特定のラインでは10倍のオーダーでした。オッズは、これが最も小さなプロジェクト以外では目立った高速化をもたらさないだろうと考えています。たとえば、プロジェクトにはhundreds of Swift=ファイルと多くのObjective-Cファイルがあり、コンパイル時間は10分以上であることがよくあります場合によっては、唯一の変更が非Swiftファイルに対するものであっても

0
NRitH