Mengapa waktu kompilasi Swift begitu lambat?

210

Saya menggunakan Xcode 6 Beta 6.

Ini adalah sesuatu yang telah menggangguku selama beberapa waktu sekarang, tetapi mencapai titik di mana itu hampir tidak dapat digunakan sekarang.

Proyek saya mulai memiliki ukuran yang layak yaitu 65 file Swift dan beberapa file Objective-C yang dijembatani (yang sebenarnya bukan penyebab masalah).

Sepertinya ada sedikit modifikasi pada setiap file Swift (seperti menambahkan ruang putih sederhana di kelas yang hampir tidak digunakan dalam aplikasi) akan menyebabkan seluruh file Swift untuk target yang ditentukan untuk dikompilasi ulang.

Setelah penyelidikan yang lebih dalam, saya telah menemukan bahwa apa yang mengambil cukup banyak 100% dari waktu kompiler adalah CompileSwiftfase di mana Xcode menjalankan swiftcperintah pada semua file Swift dari target Anda.

Saya melakukan penyelidikan lebih lanjut, dan jika saya hanya menyimpan delegasi aplikasi dengan pengontrol default kompilasi sangat cepat, tetapi karena saya menambahkan semakin banyak file proyek saya, waktu kompilasi mulai menjadi sangat lambat.

Sekarang dengan hanya 65 file sumber, dibutuhkan sekitar 8/10 detik untuk mengkompilasi setiap kali. Tidak terlalu cepat sama sekali.

Saya belum melihat posting yang membahas masalah ini kecuali yang ini , tapi itu adalah versi lama dari Xcode 6. Jadi saya bertanya-tanya apakah saya satu-satunya dalam hal ini.

MEMPERBARUI

Saya telah memeriksa beberapa proyek Swift di GitHub seperti Alamofire , Euler dan CryptoSwift , tetapi tidak satupun dari mereka yang memiliki cukup file Swift untuk dibandingkan. Satu-satunya proyek yang saya temukan yang memulai memiliki ukuran yang layak adalah SwiftHN , dan meskipun hanya memiliki selusin file sumber saya masih dapat memverifikasi hal yang sama, satu ruang sederhana dan seluruh proyek membutuhkan kompilasi ulang yang mulai mengambil sedikit waktu (2/3 detik).

Dibandingkan dengan kode Objective-C di mana penganalisis dan kompilasi sangat cepat, ini benar-benar terasa seperti Swift tidak akan pernah bisa menangani proyek-proyek besar, tapi tolong katakan padaku saya salah.

UPDATE Dengan Xcode 6 Beta 7

Masih tidak ada perbaikan apa pun. Ini mulai menjadi konyol. Dengan kurangnya #importSwift, saya benar-benar tidak melihat bagaimana Apple akan dapat mengoptimalkan ini.

UPDATE Dengan Xcode 6.3 dan Swift 1.2

Apple telah menambahkan build tambahan (dan banyak optimisasi kompiler lainnya). Anda harus memigrasi kode Anda ke Swift 1.2 untuk melihat manfaatnya, tetapi Apple menambahkan alat dalam Xcode 6.3 untuk membantu Anda melakukannya:

Masukkan deskripsi gambar di sini

NAMUN

Jangan bersukacita terlalu cepat seperti saya. Pemecah grafik yang mereka gunakan untuk membuat incremental build belum dioptimalkan dengan baik.

Memang pertama, itu tidak melihat perubahan tanda tangan fungsi jadi jika Anda menambahkan spasi di blok satu metode, semua file tergantung pada kelas itu akan dikompilasi ulang.

Kedua, sepertinya membuat pohon berdasarkan file yang dikompilasi ulang bahkan jika perubahan tidak memengaruhi mereka. Misalnya, jika Anda memindahkan ketiga kelas ini ke file yang berbeda

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

Sekarang jika Anda memodifikasi FileA, kompiler jelas akan menandai FileAuntuk dikompilasi ulang. Itu juga akan mengkompilasi ulang FileB(yang akan OK berdasarkan perubahan FileA), tetapi juga FileCkarena FileBdikompilasi ulang, dan itu sangat buruk karena FileCtidak pernah digunakan di FileAsini.

Jadi saya berharap mereka memperbaiki pemecah ketergantungan pohon ... Saya sudah membuka radar dengan kode sampel ini.

PEMBARUAN Dengan Xcode 7 beta 5 dan Swift 2.0

Kemarin Apple merilis beta 5 dan di dalam catatan rilis kita bisa melihat:

Swift Language & Compiler • Build tambahan: mengubah tubuh saja dari suatu fungsi seharusnya tidak lagi menyebabkan file dependen dibangun kembali. (15352929)

Saya telah mencobanya dan saya harus mengatakan itu berfungsi dengan baik (sungguh!) Dengan baik sekarang. Mereka sangat mengoptimalkan build inkremental dengan cepat.

Saya sangat menyarankan Anda membuat swift2.0cabang dan memperbarui kode menggunakan XCode 7 beta 5. Anda akan senang dengan penyempurnaan dari kompiler (namun saya mengatakan kondisi global XCode 7 masih lambat & bermasalah)

PEMBARUAN DENGAN Xcode 8.2

Sudah lama sejak pembaruan terakhir saya tentang masalah ini jadi ini dia.

Aplikasi kami sekarang sekitar 20 ribu baris kode Swift yang hampir secara eksklusif, yang layak tetapi tidak luar biasa. Itu mengalami migrasi cepat 2 dan dari cepat 3. Dibutuhkan sekitar 5 / 6m untuk dikompilasi pada pertengahan 2014 Macbook pro (2,5 GHz Intel Core i7) yang oke pada build bersih.

Namun build tambahan masih menjadi lelucon meskipun Apple mengklaim bahwa:

Xcode tidak akan membangun kembali seluruh target ketika hanya perubahan kecil yang terjadi. (28892475)

Jelas saya pikir banyak dari kita hanya tertawa setelah memeriksa omong kosong ini (menambahkan satu properti (pribadi!) Pribadi ke file proyek saya akan mengkompilasi ulang semuanya ...)

Saya ingin mengarahkan kalian ke utas ini di forum pengembang Apple yang memiliki beberapa informasi lebih lanjut tentang masalah ini (dan juga menghargai komunikasi pengembang Apple mengenai masalah ini sesekali)

Pada dasarnya orang telah membuat beberapa hal untuk mencoba meningkatkan pembangunan bertahap:

  1. Tambahkan HEADER_MAP_USES_VFSpengaturan proyek ketrue
  2. Nonaktifkan Find implicit dependenciesdari skema Anda
  3. Buat proyek baru dan pindahkan hierarki file Anda ke yang baru.

Saya akan mencoba solusi 3 tetapi solusi 1/2 tidak bekerja untuk kami.

Apa yang ironisnya lucu dalam seluruh situasi ini adalah bahwa melihat posting pertama tentang masalah ini kami menggunakan Xcode 6 dengan saya percaya kode swift 1 atau swift 1.1 ketika kami mencapai kelesuan kompilasi pertama dan sekarang sekitar dua tahun kemudian meskipun ada perbaikan nyata dari Apple. situasinya sama buruknya dengan Xcode 6. Sungguh ironis.

Saya benar- benar menyesal telah memilih Swift daripada Obj / C untuk proyek kami karena frustrasi sehari-hari yang terlibat. (Saya bahkan beralih ke AppCode tapi itu cerita lain)

Ngomong-ngomong, saya melihat posting SO ini memiliki 32k + view dan 143 up pada tulisan ini jadi saya kira saya bukan satu-satunya. Bertahanlah di sana, kawan-kawan meskipun pesimistis dengan situasi ini, mungkin ada sedikit cahaya di ujung terowongan.

Jika Anda punya waktu (dan keberanian!) Saya kira Apple menyambut baik radar tentang ini.

Sampai lain kali! Bersulang

PEMBARUAN DENGAN Xcode 9

Tersandung pada ini hari ini . Xcode diam-diam memperkenalkan sistem build baru untuk meningkatkan kinerja mengerikan saat ini. Anda harus mengaktifkannya melalui pengaturan ruang kerja.

masukkan deskripsi gambar di sini

Telah mencoba tetapi akan memperbarui posting ini setelah selesai. Terlihat menjanjikan.

apouche
sumber
1
Menarik! Saya bertanya-tanya apakah itu hanya optimasi yang hilang atau kebutuhan untuk mem-parsing begitu banyak file karena tidak ada file antarmuka.
zaph
2
Punya masalah serupa, dan pada akhirnya saya menyadari bahwa itu karena operator kustom yang digunakan dalam kelas entitas untuk deserialize dari JSON. Jika Anda menggunakan apa pun, saya sarankan Anda untuk mencoba mengkonversi ke fungsi normal satu per satu dan melihat apakah ada perubahan.
Antonio
4
Kompilasi menjadi lambat dalam proyek saya sejak XCode 6 beta 6. Di mana saya tidak yakin apakah itu karena perubahan dalam beta atau karena kode saya. Tetapi proyek saya bahkan belum besar (~ 40-50 file Swift).
BadmintonCat
2
Kompilasi menjadi lambat tak tertahankan saat proyek saya berkembang. Saya juga bergantung pada beberapa pod, yang saya yakin akan membuat masalah semakin buruk. Ini menggunakan rilis non-beta terbaru.
Andy
2
Build tambahan masih dibuat dalam "analisis dependensi konservatif, jadi Anda mungkin masih melihat lebih banyak file yang dibangun kembali daripada yang benar-benar diperlukan." Semoga ini akan membaik seiring waktu.
nmdias

Jawaban:

70

Ya, ternyata Rob Napier benar. Itu adalah satu file tunggal (sebenarnya satu metode) yang menyebabkan kompiler berzek.

Sekarang jangan salah paham. Swift mengkompilasi ulang semua file Anda setiap kali, tetapi yang hebat sekarang, Apple menambahkan umpan balik kompilasi real-time atas file yang dikompilasinya, jadi Xcode 6 GM sekarang menunjukkan file Swift mana yang sedang dikompilasi dan status kompilasi secara real time seperti yang Anda lihat di tangkapan layar ini:

Masukkan deskripsi gambar di sini

Jadi ini sangat berguna untuk mengetahui file mana yang memakan waktu begitu lama. Dalam kasus saya ini adalah potongan kode ini:

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

return dic.copy() as NSDictionary

karena properti titleitu tipe var title:String?dan tidak NSString. Kompilator menjadi gila ketika menambahkannya ke NSMutableDictionary.

Mengubahnya menjadi:

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

return dic.copy() as NSDictionary

membuat kompilasi berjalan dari 10/15 detik (mungkin lebih) ke satu detik ... luar biasa.

apouche
sumber
3
Terima kasih telah menindaklanjuti dengan jawabannya. Ini mungkin sangat berguna bagi orang lain yang mengejar di sana mesin tipe-inferensi macet selama kompilasi.
Rob Napier
1
Di mana Anda mendapatkan tampilan ini @apouche? Saya tidak melihatnya di xcode
Eric
2
Anda perlu membuka asisten debug (CMD + 8) dan klik build saat ini
apouche
1
ya saya yakin Apple akan mengoptimalkan ini nanti, jika tidak, melakukan proyek dunia nyata dengan cepat akan berakhir di sana-sini.
apouche
1
Bagaimana saya bisa sampai ke alat ini yang menunjukkan file mana yang sedang dikompilasi?
jgvb
42

Kami telah mencoba beberapa hal untuk mengatasi hal ini karena kami memiliki sekitar 100 rb baris kode Swift dan 300 rb baris kode ObjC.

Langkah pertama kami adalah mengoptimalkan semua fungsi sesuai dengan fungsi, mengkompilasi waktu keluaran (mis. Seperti dijelaskan di sini https://thatthinginswift.com/debug-long-compile-times-swift/ )

Selanjutnya kami menulis skrip untuk menggabungkan semua file cepat menjadi satu file, ini memecah tingkat akses tetapi membawa waktu kompilasi kami dari 5-6 menit hingga ~ 1 menit.

Ini sekarang mati karena kami bertanya kepada Apple tentang ini dan mereka menyarankan kami harus melakukan yang berikut:

  1. Aktifkan 'optimasi seluruh modul' di pengaturan pembangunan 'Swift Compiler - Code Generation'. Pilih'Fast, Whole Module Optimization'

masukkan deskripsi gambar di sini

  1. Di 'Swift Compiler - Custom Flags', untuk build pengembangan Anda, tambahkan '-Onone'

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Ketika flag-flag ini diset, kompiler akan mengkompilasi semua file Swift dalam satu langkah. Kami menemukan dengan skrip gabungan kami ini jauh lebih cepat daripada mengkompilasi file secara individual. Namun, tanpa ' -Onone'override ' , itu juga akan mengoptimalkan seluruh modul, yang lebih lambat. Ketika kami mengatur '-Onone'bendera di bendera Swift lainnya, ia menghentikan pengoptimalan, tetapi tidak berhenti mengkompilasi semua file Swift dalam satu langkah.

Untuk info lebih lanjut tentang optimasi seluruh modul, lihat posting blog Apple di sini - https://swift.org/blog/whole-module-optimizations/

Kami telah menemukan pengaturan ini memungkinkan kode Swift kami untuk dikompilasi dalam 30 detik :-) Saya tidak punya bukti bagaimana itu akan bekerja pada proyek lain, tapi saya sarankan mencobanya jika waktu kompilasi Swift masih menjadi masalah bagi Anda.

Catatan untuk build App store Anda, Anda harus meninggalkan '-Onone'benderanya, karena optimasi disarankan untuk build produksi.

Sam Stow
sumber
4
Terima kasih banyak atas saran ini! Saya benar-benar tidak mengerti mengapa tidak ada yang seperti itu dalam sumber resmi (setidaknya mudah ditemukan), misalnya artikel yang Anda sebutkan harus (harus!) Memiliki komentar tentang -Onone. Kami tidak dapat menggunakan optimasi seluruh modul untuk saat ini karena membuat compiler crash ... Tetapi saran Anda memberi dorongan hampir x10 pada kecepatan build kami. Di MacBook Air (tahunan 2013) itu dibangun sekitar 8 menit, sekarang turun menjadi sekitar 1 menit dan setengah dari waktu yang dihabiskannya untuk beralih antar target (kami memiliki aplikasi, ekstensi, dan beberapa kerangka kerja in-house) dan menyusun storyboard
Ilya Puchka
Saya juga telah menguji metode ini dan hanya metode yang disebutkan yang mencakup -Satu dan itu mengurangi waktu pembangunan secara signifikan.
Vlad
Bekerja dengan punyaku juga. Menggunakan -Ononebantuan untuk mengurangi waktu pembuatan. Terima kasih banyak teman!
nahung89
34

Sepertinya tidak ada hubungannya dengan ukuran proyek Anda. Mungkin beberapa kode tertentu, bahkan mungkin hanya satu baris. Anda dapat menguji ini dengan mencoba mengkompilasi satu file pada suatu waktu daripada keseluruhan proyek. Atau coba tonton build log untuk melihat file mana yang memakan waktu begitu lama.

Sebagai contoh jenis kode yang dapat menyebabkan masalah, inti 38-baris ini membutuhkan waktu lebih dari satu menit untuk dikompilasi dalam beta7. Semua itu disebabkan oleh satu blok ini:

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

Sederhanakan bahwa hanya dengan satu atau dua baris dan kompilasi hampir secara instan. Masalahnya adalah sesuatu tentang hal ini yang menyebabkan pertumbuhan eksponensial (kemungkinan pertumbuhan faktorial) dalam kompiler. Jelas itu tidak ideal, dan jika Anda dapat mengisolasi situasi seperti itu, Anda harus membuka radar untuk membantu menyelesaikan masalah tersebut.

Rob Napier
sumber
Saya tidak yakin Anda melihat komentar saya mengenai CompileSwiftfase ini. Dibutuhkan semua file cepat bahkan jika hanya satu yang dimodifikasi. Jadi jika itu adalah satu file yang membutuhkan waktu (yang saya sangat ragu), kompiler tidak akan pernah memberi tahu Anda yang mana itu.
apouche
10
Anda dapat mengkompilasi file individual menggunakan swiftcuntuk melihat berapa lama.
Rob Napier
Saya minta maaf karena tidak memberi Anda hadiah karena saya awalnya tidak percaya. Saya juga mencoba untuk mengkompilasi file satu per satu tetapi itu rumit untuk dilakukan (harus memberikan kerangka kerja dengan benar, dan deps setiap kali) jadi saya menyerah. Silakan lihat jawaban terakhir saya untuk posting ini untuk penjelasan lengkap
apouche
Saya tidak berpikir itu berdasarkan ukuran proyek. Proyek saya hanya memiliki 4 file cepat dan tiba-tiba mulai kompilasi sangat lambat. Itu pencahayaan cepat kemarin. Tidak dapat menaruh jari saya pada apa pun yang saya lakukan pada proyek saya khususnya kecuali menambahkan ikon dan meluncurkan gambar.
Travis M.
33

Jika Anda mencoba mengidentifikasi file tertentu yang memperlambat waktu kompilasi Anda, Anda bisa mencoba mengkompilasinya dari baris perintah Anda melalui xctool yang akan memberi Anda waktu kompilasi file per file.

Hal yang perlu diperhatikan adalah, secara default, ia membangun 2 file secara bersamaan per setiap inti CPU, dan tidak akan memberi Anda waktu "bersih" yang terlewati, tetapi waktu "pengguna" absolut. Dengan cara ini semua waktu bahkan keluar antara file yang diparalelkan dan terlihat sangat mirip.

Untuk mengatasinya, atur -jobsflag ke 1 , sehingga tidak memaralelkan pembuatan file. Ini akan memakan waktu lebih lama, tetapi pada akhirnya Anda akan memiliki waktu kompilasi "bersih" sehingga Anda dapat membandingkan file per file.

Ini adalah contoh perintah yang harus melakukan trik:

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

Output dari fase "Compile Swift files" akan seperti:

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

Dari hasil ini Anda dapat dengan cepat mengidentifikasi file mana yang membutuhkan waktu lebih lama daripada yang lain untuk dikompilasi. Selain itu, Anda dapat menentukan dengan akurasi tinggi apakah refactoring Anda (gips eksplisit, petunjuk ketik, dll ...) menurunkan waktu kompilasi untuk file tertentu atau tidak.

CATATAN: secara teknis Anda juga bisa melakukannya dengan xcodebuildtetapi outputnya sangat bertele-tele dan sulit dikonsumsi.

Andrea Sprega
sumber
1
Pastikan saja Anda telah Mengoptimalkan Modul Utuh proyek Anda ke false, atau itu tidak akan memisahkan file swift individu.
sabes
1
Lihat Swift CompilerOptimization LeveluntukFast, Whole Module Optimization [-O -whole-module-optimization]
Matt
26

Dalam kasus saya, Xcode 7 tidak ada bedanya sama sekali. Saya memiliki beberapa fungsi yang memerlukan beberapa detik untuk dikompilasi.

Contoh

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

Setelah membuka bungkus opsi, waktu pembuatan turun 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)

Lihat lebih banyak contoh di posting ini dan posting ini .

Build Time Analyzer untuk Xcode

Saya mengembangkan plug-in Xcode yang mungkin berguna bagi siapa saja yang mengalami masalah ini.

gambar

Tampaknya ada perbaikan datang di Swift 3 jadi semoga kita akan melihat kompilasi kode Swift kami lebih cepat.

Robert Gummesson
sumber
Luar biasa, Semoga saya bisa memberi Anda Lebih dari +1. Anda benar dan plugin Anda juga hebat. Saya telah menggunakan itu dan waktu build saya semakin turun, yang berarti pengembangan super cepat karena kadang-kadang opsional ini adalah mimpi buruk dan menyebabkan kompiler melambat.
hardikdevios
Fantastis! Alat Anda banyak membantu saya. Terima kasih
Phil
Plugin hebat - Sangat berguna! Terima kasih
365SplendidSuns
@ Robert Gummesson, apakah kita punya alat untuk Kode Objective-C?
Ashok
19

Mungkin kita tidak dapat memperbaiki kompiler Swift, tetapi sesuatu yang dapat kita perbaiki adalah kode kita!

Ada pilihan tersembunyi di Swift compiler yang print interval waktu yang tepat yang compiler dibutuhkan untuk mengkompilasi setiap fungsi tunggal: -Xfrontend -debug-time-function-bodies. Hal ini memungkinkan kami untuk menemukan hambatan dalam kode kami dan secara signifikan meningkatkan waktu kompilasi.

Sederhana jalankan hal berikut di terminal dan analisis hasil:

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

Brian Irace yang luar biasa menulis artikel yang luar biasa tentang hal ini Memprofilkan waktu kompilasi Swift Anda .

Valentin Shergin
sumber
2
Bagi mereka dengan zsh alias grep='noglob grep'pertama, grep lain tidak akan bekerja
Jaime Agudo
16

Solusinya adalah casting.

Saya memiliki banyak sekali kamus, seperti ini:

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

Butuh waktu sekitar 40 menit untuk mengkompilasinya. Sampai saya membuat kamus-kamus seperti ini:

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

Ini bekerja untuk hampir setiap masalah lain yang saya temui berkenaan dengan tipe data yang saya kodekan ke dalam aplikasi saya.

YichenBman
sumber
6
baik ya, itu bagian dari optimisasi yang Anda lakukan untuk meningkatkan waktu kompilasi, tetapi masih masalah utama dengan kompiler swift saat ini, adalah bahwa ia masih mengkompilasi ulang semua file swift tunggal setiap kali Anda membuat sedikit modifikasi.
apouche
4
Itu akan lucu jika tidak begitu sedih.
Tom Andersen
15

Satu hal yang perlu diperhatikan adalah bahwa mesin inferensi tipe Swift bisa sangat lambat dengan tipe bersarang. Anda bisa mendapatkan ide umum tentang apa yang menyebabkan kelambatan dengan menonton log pembangunan untuk unit kompilasi individu yang membutuhkan waktu lama dan kemudian menyalin & menempelkan perintah Xcode-spawned penuh ke jendela Terminal dan kemudian menekan CTRL- \ untuk mendapatkan beberapa diagnosa. Lihatlah http://blog.impathic.com/post/99647568844/debugging-slow-swift-compile-times untuk contoh lengkap.

marcprux
sumber
Bagi saya itu jawaban terbaik (lihat tautan). Saya dapat dengan mudah menemukan dua baris berbeda yang merupakan masalah dan menyelesaikannya dengan menguraikan baris saya menjadi garis yang lebih kecil.
Nico
Itu adalah jawaban yang sangat berguna karena ini menunjukkan bagaimana menemukan di mana kompiler menjadi gila. Dalam kasus saya itu adalah sebagai berikut: 'curScore [curPlayer% 2] + curScore [2 + curPlayer% 2] == 3 && maker% 2 == curPlayer% 2' Segera setelah saya memindahkannya dari 'jika' ke 'biarkan ', itu menghasilkan "ekspresi terlalu rumit untuk dipecahkan dalam waktu yang wajar; pertimbangkan memecah ekspresi menjadi sub-ekspresi yang berbeda"
Dmitry
Ini jelas merupakan cara yang paling membantu untuk menyelesaikan masalah ini.
Richard Venable
9

Juga pastikan bahwa ketika mengkompilasi untuk debug (baik Swift atau Objective-C), Anda mengatur untuk Membangun Arsitektur Aktif Saja:

masukkan deskripsi gambar di sini

Rivera
sumber
6

Karena semua hal ini dalam Beta, dan karena kompiler Swift (setidaknya pada hari ini) tidak terbuka, saya kira tidak ada jawaban nyata untuk pertanyaan Anda.

Pertama-tama, membandingkan Objective-C dengan Swift compiler entah bagaimana kejam. Swift masih dalam Beta, dan saya yakin Apple bekerja dalam menyediakan fungsionalitas dan memperbaiki bug, lebih dari memberikan kecepatan kilat (Anda tidak mulai membangun rumah dengan membeli furnitur). Saya kira Apple akan mengoptimalkan kompiler pada waktunya.

Jika karena alasan tertentu semua file sumber harus dikompilasi secara lengkap, sebuah opsi mungkin untuk membuat modul / pustaka yang terpisah. Tetapi opsi ini belum memungkinkan, karena Swift tidak dapat mengizinkan pustaka sampai bahasanya stabil.

Dugaan saya adalah mereka akan mengoptimalkan kompiler. Untuk alasan yang sama bahwa kita tidak dapat membuat modul pra-kompilasi, bisa jadi kompiler perlu mengkompilasi semuanya dari awal. Tetapi begitu bahasa mencapai versi stabil dan format binari tidak berubah lagi, kita akan dapat membuat perpustakaan kita, dan mungkin (?) Kompiler juga akan dapat mengoptimalkan pekerjaannya.

Hanya menebak, hanya Apple yang tahu ...

George
sumber
"Untuk alasan yang sama bahwa kita tidak dapat membuat modul pra-kompilasi, bisa jadi kompiler perlu mengkompilasi semuanya dari awal." pengamatan yang bagus, belum pernah memikirkannya seperti itu sebelumnya.
chakrit
1
2017 dan masih lambat
Pedro Paulo Amorim
2017 dengan Xcode 9 dan sistem build baru dan masih lambat
pableiros
2018 dengan Xcode 9, saya punya proyek dengan lebih dari 50 file swift, jika saya melakukan clean build, sekarang sudah melewati tanda 5 menit dan kompilasi saya belum selesai.
Chen Li Yong
5

Untuk Xcode 8, buka pengaturan proyek, lalu Editor> Tambahkan Pengaturan Pengaturan> Tambahkan Pengaturan Buatan Pengguna, dan tambahkan berikut ini:

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

Menambahkan bendera ini menjatuhkan waktu kompilasi build-bangunan kami dari 7 menit menjadi 65-an untuk proyek cepat 40KLOC, secara ajaib. Juga dapat mengkonfirmasi 2 teman telah melihat peningkatan serupa pada proyek perusahaan.

Saya hanya bisa berasumsi ini adalah semacam bug di Xcode 8.0

EDIT: Tampaknya tidak berfungsi lagi di Xcode 8.3 untuk sebagian orang.

Chris
sumber
2
Di mana "pengaturan proyek" tolong?
Raniys
@Raniys Klik pada ikon biru di tingkat root di panel kiri di Xcode.
Chris
Saya menemukan bahwa pada Xcode 8.3 (non-beta) ini tidak lagi berfungsi dalam kasus saya :(
Chris
4

Sayangnya, kompiler Swift masih belum dioptimalkan untuk kompilasi yang cepat dan tambahan (pada Xcode 6.3 beta). Sementara itu Anda dapat menggunakan beberapa teknik berikut untuk meningkatkan waktu kompilasi Swift:

  • Membagi aplikasi menjadi Kerangka kerja untuk mengurangi dampak kompilasi. Namun ketahuilah bahwa Anda harus menghindari ketergantungan siklik di aplikasi Anda. Untuk info lebih lanjut tentang topik ini, periksa posting ini: http://bits.citrusbyte.com/improving-swift-compile-time/

  • Gunakan Swift untuk bagian-bagian proyek Anda yang cukup stabil dan tidak sering berubah. Untuk area lain di mana Anda perlu mengubah sangat sering atau area yang membutuhkan banyak kompilasi / menjalankan iterasi untuk menjadi lengkap (hampir semua hal terkait UI), lebih baik gunakan Objective-C dengan pendekatan campuran-dan-cocokkan.

  • Coba injeksi kode runtime dengan 'Injeksi untuk Xcode'

  • Gunakan metode roopc: http://roopc.net/posts/2014/speeding-up-swift-builds/

  • Meringankan mesin inferensi tipe cepat dengan memberikan beberapa petunjuk dengan gips eksplisit.

vorterixe
sumber
4

Susunan deret cepat dan kamus tampaknya menjadi penyebab yang cukup populer untuk ini (khususnya bagi Anda yang berasal dari latar belakang Ruby ), yaitu,

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"]

mungkin akan menjadi penyebab di mana ini harus memperbaikinya:

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

Untuk debug dan pengujian, pastikan untuk menggunakan pengaturan berikut untuk memangkas waktu kompilasi dari sekitar 20 menit menjadi kurang dari 2 menit,

  1. Dalam pengaturan pembangunan proyek, cari "Optimasi" Ubah Debug menjadi "Tercepat [-O3]" atau di atasnya.
  2. Atur Build untuk Arsitektur Aktif: YES
  3. Format informasi debug: DWARF
  4. Optimalisasi Seluruh Modul: TIDAK

Saya menghabiskan banyak waktu menunggu proyek untuk membangun hanya untuk menyadari bahwa saya harus membuat satu perubahan kecil dan harus menunggu selama 30 menit untuk mengujinya. Ini adalah pengaturan yang berfungsi untuk saya. (Saya masih bereksperimen dengan pengaturan)

Tapi, pastikan Anda setidaknya menetapkan "DWARF with dSYM" (jika Anda ingin memonitor aplikasi Anda) dan Build Active Architecture ke "NO" untuk rilis / Pengarsipan untuk mendorong ke iTunes Connect (saya ingat menghabiskan beberapa jam di sini juga).

Mahesh
sumber
4
Saya mungkin salah, tetapi tidakkah menetapkan peningkatan level optimasi benar-benar meningkatkan waktu pembuatan? Level optimisasi akan meningkatkan kinerja runtime.
Air Terjun Michael
1
Set Build for Active Architecture: YESmemberi saya pengurangan sekitar 45% dalam waktu kompilasi. Terima kasih banyak.
Jean Le Moignan
4

Compiler menghabiskan banyak waktu untuk menyimpulkan dan memeriksa tipenya. Jadi menambahkan anotasi tipe sangat membantu kompiler.

Jika Anda memiliki banyak panggilan fungsi dirantai seperti

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

Kemudian kompiler membutuhkan waktu untuk mencari tahu seperti apa sumseharusnya. Menambahkan jenis ini membantu. Yang juga membantu adalah menarik langkah-langkah berselang ke variabel yang terpisah.

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: +)

Khusus untuk tipe numerik CGFloat, Intini bisa banyak membantu. Seperti angka literal2 dapat mewakili banyak jenis numerik yang berbeda. Jadi kompiler perlu mencari tahu dari konteks yang mana itu.

Fungsi yang membutuhkan banyak waktu untuk terlihat seperti +juga harus dihindari. Menggunakan beberapa +untuk menggabungkan beberapa array lambat karena kompiler perlu mencari tahu implementasi yang +harus dipanggil untuk masing-masing +. Jadi gunakan var a: [Foo]dengan append()sebagai gantinya jika memungkinkan.

Anda dapat menambahkan peringatan untuk mendeteksi fungsi mana yang lambat dikompilasi dalam Xcode .

Dalam Pengaturan Bangun untuk pencarian target Anda untuk Bendera Swift Lain dan tambahkan

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

untuk memperingatkan untuk setiap fungsi yang membutuhkan waktu lebih dari 100 ms untuk dikompilasi.

orkoden
sumber
4

Untuk proyek yang mencampur Objective-C dan Swift kode, kita dapat mengatur -enable-bridging-pchdi Other Swift Flags. Dengan ini, bridging header hanya diurai satu kali, dan hasilnya (file "precompiled header" atau "PCH" sementara) di-cache dan digunakan kembali di semua file Swift di target. Apple mengklaim itu mengurangi waktu pembangunan sebesar 30%. Tautan Referensi:

CATATAN: Ini hanya berfungsi untuk Swift 3.1 dan yang lebih baru.

iHS
sumber
2

Mem-boot ulang Mac saya melakukan keajaiban untuk masalah ini. Saya beralih dari 15 menit ke 30 detik hanya dengan me-reboot.

Sigma4Life
sumber
1

Waktu kompilasi Swift ditingkatkan dalam Xcode 6.3 baru

Peningkatan kompiler

Kompiler Swift 1.2 dirancang untuk menjadi lebih stabil dan untuk meningkatkan kinerja dalam segala hal. Perubahan ini juga memberikan pengalaman yang lebih baik ketika bekerja dengan Swift di Xcode. Beberapa peningkatan yang paling terlihat meliputi:

Membangun bertahap

File sumber yang tidak berubah tidak akan lagi dikompilasi ulang secara default, yang secara signifikan akan meningkatkan waktu pembuatan untuk kebanyakan kasus umum. Perubahan struktural yang lebih besar pada kode Anda mungkin masih memerlukan beberapa file untuk dibangun kembali.

Eksekusi yang lebih cepat

Debug build menghasilkan binari yang berjalan jauh lebih cepat, dan optimasi baru menghasilkan kinerja rilis build yang lebih baik.

Diagnosis kompiler yang lebih baik

Pesan kesalahan dan peringatan yang lebih jelas, bersama dengan Fix-nya yang baru, membuatnya lebih mudah untuk menulis kode Swift 1.2 yang tepat.

Peningkatan stabilitas

Kecelakaan compiler yang paling umum telah diperbaiki. Anda juga harus melihat lebih sedikit peringatan SourceKit dalam editor Xcode.

Vojtech Vrbka
sumber
0

Inilah kasus lain yang dapat menyebabkan perlambatan besar dengan inferensi tipe. Operator penggabungan .

Mengubah garis seperti:

abs(some_optional_variable ?? 0)

untuk

abs((some_optional_variable ?? 0) as VARIABLE_TYPE)

membantu membawa waktu kompilasi dari 70 ke 13

Harry Meksiko
sumber
0

Tidak ada yang berhasil untuk saya di Xcode 6.3.1 - ketika saya menambahkan sekitar 100 file Swift Xcode digantung secara acak pada build dan / atau pengindeksan. Saya sudah mencoba opsi modular tanpa hasil.

Menginstal dan menggunakan Xcode 6.4 Beta benar-benar bekerja untuk saya.

hris.to
sumber
0

Ini telah bekerja seperti sulap bagi saya - Mempercepat Kompilasi Cepat . Ini mengurangi waktu kompilasi menjadi 3 menit dari 10 menit.

Ia mengatakan Anda harus mengaktifkan Whole Module Optimizationsambil menambahkan -Ononedi Other Swift Flags.

Saya menggunakan Swift 3pada Xcode 8.3/Xcode 8.2 .

Menempa
sumber
0

Mencampur integer literal dan float literal dalam satu ekspresi juga menyebabkan waktu kompilasi yang lama.

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

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

Banyak 1000 + ms ekspresi waktu kompilasi dikurangi menjadi 10 ~ 100 ms setelah saya meletakkan .0literer setelah integer.

Chen OT
sumber