Чому час компіляції Swift так повільний?


210

Я використовую Xcode 6 Beta 6.

Це те, що клопоче мене вже деякий час, але це доходить до того моменту, коли він зараз ледве придатний.

Мій проект починає мати пристойний розмір 65 файлів Swift та декілька мостових файлів Objective-C (що насправді не є причиною проблеми).

Здається, що будь-яка незначна зміна будь-якого файлу Swift (наприклад, додавання простого пробілу в клас, який ледь використовується в додатку) призведе до перекомпіляції всіх файлів Swift для вказаної цілі.

Після більш глибокого дослідження я виявив, що те, що займає майже 100% часу компілятора, - це CompileSwiftфаза, коли Xcode виконує swiftcкоманду на всіх файлах Swift вашої цілі.

Я провів деяке подальше дослідження, і якщо я залишаю лише делегата програми за допомогою контролера за замовчуванням, компіляція дуже швидка, але, оскільки я додавав все більше моїх файлів проекту, час компіляції починав надто повільно.

Зараз, маючи лише 65 вихідних файлів, щоразу збирається близько 8/10 секунд. Не дуже швидко .

Я не бачив жодної публікації, яка б обговорювала цю проблему, окрім цієї , але це була стара версія Xcode 6. Тож мені цікаво, чи я єдиний у цьому випадку.

ОНОВЛЕННЯ

Я перевірив кілька проектів Swift на GitHub, таких як Alamofire , Euler та CryptoSwift , але жоден з них не мав достатньо файлів Swift, щоб насправді можна порівняти. Єдиний проект, який я виявив, що запускав пристойний розмір, був SwiftHN , і, хоча у нього було лише десяток вихідних файлів, я все ще зміг перевірити те саме, один простий простір і весь проект потребував перекомпіляції, яка починала брати мало часу (2/3 секунди).

У порівнянні з кодом Objective-C, коли і аналізатор, і компіляція палають швидко, це справді відчуває, що Свіфт ніколи не зможе впоратися з великими проектами, але, будь ласка, скажіть мені, що я помиляюся.

ОНОВЛЕННЯ Xcode 6 Beta 7

Досі ніякого поліпшення. Це починає ставати смішним. З нестачею #importу Swift я дійсно не бачу, як Apple коли-небудь зможе оптимізувати це.

ОНОВЛЕННЯ З Xcode 6.3 та Swift 1.2

Apple додала додаткові нарощування (та багато інших оптимізацій компілятора). Вам потрібно перенести свій код до Swift 1.2, щоб побачити ці переваги, але Apple додала інструмент у Xcode 6.3, який допоможе вам зробити це:

Введіть тут опис зображення

ЗАРАЗ

Не радійте занадто швидко, як я. Розв’язувач графіків, який вони використовують для нарощення нарощування, ще не дуже оптимізований.

Насправді спочатку він не розглядає зміни підписів функції, тому якщо ви додасте пробіл у блоці одного методу, всі файли залежно від цього класу будуть перекомпільовані.

По-друге, схоже, дерево створюється на основі файлів, які були перекомпільовані, навіть якщо зміна на них не впливає. Наприклад, якщо ви перемістите ці три класи в різні файли

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

Тепер, якщо ви модифікуєте FileA, компілятор, очевидно, позначає FileAперекомпіляцію. Він також буде перекомпільований FileB(це було б нормально на основі змін до FileA), але також FileCтому, що FileBвін перекомпільований, і це дуже погано, оскільки тут FileCніколи не використовується FileA.

Тож я сподіваюся, що вони вдосконалюють вирішувач цього дерева залежності ... Я відкрив радар із цим зразковим кодом.

ОНОВЛЕННЯ З Xcode 7 beta 5 та Swift 2.0

Вчора Apple випустила бета-версію 5, і всередині нотаток до випуску ми могли побачити:

Швидка мова та компілятор • Інкрементальна побудова: зміна лише корпусу функції більше не повинна спричиняти перебудову залежних файлів. (15352929)

Я спробував це, і я повинен сказати, що він працює (справді!) Добре зараз. Вони значно оптимізували нарощування наростів швидко.

Я настійно рекомендую створити swift2.0гілку та оновлювати код за допомогою XCode 7 beta 5. Вас порадують вдосконалення компілятора (однак я б сказав, що глобальний стан XCode 7 все ще повільний і непомітний)

ОНОВЛЕННЯ З Xcode 8.2

Минуло час з мого останнього оновлення з цього питання, ось ось воно.

Наше додаток нараховує приблизно 20 тис. Рядків майже виключно коду Swift, що є пристойним, але не видатним. Він зазнав швидкої міграції 2, а потім швидкої міграції 3. На середину 2014 року Macbook pro (2,5 ГГц Intel Core i7) потрібно близько 5/6 м, що добре в чистоті.

Однак додаткове нарощування все ще є жартом, незважаючи на те, що Apple заявляє, що:

Xcode не відновить цілі, якщо відбулися лише невеликі зміни. (28892475)

Очевидно, я думаю, що багато хто з нас просто посміялися після перевірки цієї дурниці (додавання одного приватного (приватного!) Властивості до будь-якого файлу мого проекту перекомпілює все це ...)

Я хотів би вказати вам, хлопці, на цю тему на форумах розробників Apple, де є додаткова інформація про цю проблему (а також високо цінується спілкування Apple Dev з цього питання)

В основному люди придумали кілька речей, щоб спробувати покращити нарощення:

  1. Додайте HEADER_MAP_USES_VFSналаштування проекту доtrue
  2. Відключення Find implicit dependenciesвід вашої схеми
  3. Створіть новий проект та перемістіть ієрархію файлів до нового.

Я спробую розв’язати рішення 3, але рішення 1/2 не працювало для нас.

Іронічно смішно у всій цій ситуації полягає в тому, що, дивлячись на першу публікацію з цього питання, ми використовували Xcode 6, я вважаю, що швидкий код 1 або swift 1.1, коли ми досягли першої млявості компіляції, а тепер приблизно через два роки, незважаючи на фактичні вдосконалення від Apple, ситуація так само погана, як і з Xcode 6. Як іронічно.

Я дійсно шкодую, що вибрав Swift над Obj / C для нашого проекту через щоденні фрустрації, які він пов’язаний. (Я навіть переходжу на AppCode, але це вже інша історія)

У будь-якому випадку я бачу, що ця публікація має 32 тис. + Переглядів і 143 підйоми на цей час, тому я думаю, що я не єдиний. Повісьте там, хлопці, незважаючи на песимізм щодо цієї ситуації, може бути світло в кінці тунелю.

Якщо у вас є час (і сміливість!), Я думаю, Apple вітає радіолокацію з цього приводу.

До наступного разу! Ура

ОНОВЛЕННЯ Xcode 9

Натрапляйте на це сьогодні. Xcode тихо представив нову систему складання, щоб покращити поточну жахливу продуктивність. Ви повинні ввімкнути це через налаштування робочої області.

введіть тут опис зображення

Спробували ще, але оновлять цю публікацію після її завершення. Хоча це виглядає перспективно.


1
Цікаво! Цікаво, чи це просто відсутня оптимізація чи необхідність розбору стільки файлів, оскільки файлів інтерфейсу немає.
zaph

2
У мене були подібні проблеми, і врешті-решт я зрозумів, що це через десаріалізацію з JSON через користувацькі оператори, які використовуються в класах сущностей. Якщо ви використовуєте будь-який, я пропоную вам спробувати перейти до нормальної функції по черзі і побачити, чи щось зміниться.
Антоніо

4
У моєму проекті компіляція стала зухвало повільною, починаючи з XCode 6 beta 6. Де я не впевнений, чи це пов’язано зі зміною бета-версії чи через мій код. Але мій проект ще не великий (~ 40-50 файлів Swift).
BadmintonCat

2
Зростання мого проекту стало нестерпно повільним. Я також залежу від декількох стручків, що, я впевнений, переживає проблему. Для цього використовується нещодавній бета-версія.
Енді

2
Інкрементальна збірка все ще робиться в "консервативному аналізі залежності, тому ви все ще можете побачити більше файлів для відновлення, ніж абсолютно необхідних". Сподіваємось, воно з часом покращиться.
nmdias

Відповіді:


70

Що ж, виявилося, що Роб Нап'єр мав рацію. Саме один файл (власне один метод) змушував компілятор переходити на берзек.

Тепер не зрозумійте мене неправильно. 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 секунд (можливо, навіть більше) до однієї секунди ... дивовижно.


3
Дякуємо, що продовжили відповідь. Це може бути дуже корисно для інших, що переслідують там, коли двигун виводу типу застрягає під час компіляції.
Роб Нап’єр

1
Де ви потрапили до цього погляду @apouche? Я не бачу його в xcode
Ерік

2
Вам потрібно відкрити помічника налагодження (CMD + 8) та натиснути на поточну збірку
apouche

1
так, я впевнений, що Apple оптимізує це пізніше, інакше швидке виконання реальних проектів буде приречене тут і там.
apouche

1
Як я можу отримати цей інструмент, який показує, які файли збираються?
jgvb

42

Ми намагалися боротися з цим досить багато, оскільки у нас є близько 100 тис. Рядків коду Swift та 300k рядків коду ObjC.

Нашим першим кроком було оптимізація всіх функцій відповідно до виводу часу компіляції функцій (наприклад, як описано тут https://thatthinginswift.com/debug-long-compile-times-swift/ )

Далі ми написали сценарій для об'єднання всіх швидких файлів в один файл, це розбиває рівні доступу, але це принесло час компіляції від 5-6 хв до ~ 1хвилини.

Зараз це не існує, тому що ми попросили Apple про це, і вони порадили нам зробити наступне:

  1. Увімкніть «оптимізацію всього модуля» в налаштуваннях збірки «Швидкий компілятор - генерація коду». Виберіть'Fast, Whole Module Optimization'

введіть тут опис зображення

  1. Додайте в "Швидкий компілятор - спеціальні прапори" для створення вашої розробки '-Onone'

введіть тут опис зображення введіть тут опис зображення

Коли ці прапори встановлені, компілятор збирає всі файли Swift за один крок. Ми виявили, що за допомогою нашого сценарію злиття це набагато швидше, ніж компіляція файлів окремо. Однак без ' -Onone'перебору, це також оптимізує весь модуль, який повільніше. Коли ми встановлюємо '-Onone'прапор в інших прапорах Swift, він зупиняє оптимізацію, але він не припиняє збирати всі файли Swift за один крок.

Для отримання додаткової інформації про оптимізацію цілого модуля, ознайомтеся з повідомленням у щоденнику компанії Apple - https://swift.org/blog/whole-module-optimizations/

Ми виявили, що ці налаштування дозволяють нашому коду Swift збиратись за 30 секунд :-) Я не маю доказів того, як він би працював на інших проектах, але я пропоную спробувати, якщо час компіляції Swift все ще є проблемою для вас.

Зауважте, що для вашої збірки магазинів додатків вам слід не залишити '-Onone'прапор, оскільки оптимізація рекомендується використовувати для виробничих збірок.


4
Велике спасибі за цю пораду! Я просто не розумію, чому немає нічого подібного в офіційних джерелах (принаймні легко знайти), наприклад стаття, про яку ви згадуєте, повинна (повинна!) Мати зауваження -Onone. Наразі ми не можемо використовувати оптимізацію цілого модуля, оскільки це робить збій компілятора ... Але ваша порада дає майже x10 прискорення нашої швидкості збирання. На MacBook Air (щорічно 2013 р.) Він будувався близько 8 хвилин, зараз він зменшується приблизно на 1 хвилину та половину цього часу, він витрачає на перемикання між цілями (у нас є додаток, розширення та декілька внутрішніх фреймворків) та на складання розкадрів
Ілля Пучка

Я також перевірив цей метод, і це лише згаданий метод, який включає в себе -Onone, і це значно скорочує час збірки.
Влад

Працюйте і з моєю. Використання -Ononeдовідки для скорочення строків збирання. Дякую, товариш!
nahung89

34

Це, мабуть, мало стосується розміру вашого проекту. Це, мабуть, якийсь конкретний фрагмент коду, можливо, навіть лише один рядок. Ви можете перевірити це, намагаючись зібрати один файл одночасно, а не весь проект. Або спробуйте переглянути журнали збирання, щоб побачити, який файл займає так довго.

Як приклад видів коду, який може спричинити неполадки, цей 38-рядковий суть займає більше хвилини, ніж збирати в бета7. Все це викликано цим одним блоком:

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

Спростіть це лише рядком або двома, і він складається майже миттєво. Проблема полягає в тому, що це викликає експоненціальне зростання (можливо, факторне зростання) у компіляторі. Очевидно, що це не ідеально, і якщо ви можете виокремити подібні ситуації, вам слід відкрити радари, які допоможуть виправити ці проблеми.


Я не впевнений, що ви бачили мій коментар щодо CompileSwiftетапу. Це займає всі швидкі файли, навіть якщо було змінено лише один. Тож якщо це один файл, який потребує певного часу (в чому я дуже сумніваюся), компілятор ніколи не скаже вам, який це.
apouche

10
Ви можете компілювати окремі файли, використовуючи, swiftcщоб побачити, скільки часу вони займають.
Роб Нап’єр

Прошу вибачення за те, що не надаю вам винагороди, оскільки спочатку не вірю. Я також намагався компілювати файли по одному, але це було громіздко (потрібно було правильно давати рамки та деп-файли кожного разу), тому я здався. Будь ласка, дивіться мою останню відповідь на цю публікацію для повного пояснення
apouche

Я не думаю, що це розмір проекту. Мій проект має лише 4 швидких файли і раптом почав збирати неймовірно повільно. Вчора швидко загорялося. Я не можу прикласти палець до нічого, що я зробив для свого проекту, зокрема, крім додавання піктограми та запуску зображень.
Травіс М.

33

Якщо ви намагаєтеся визначити конкретні файли, які сповільнюють час компіляції, ви можете спробувати компілювати його з вашого командного рядка через xctool, який дасть вам час складання файл за файлом.

Варто зазначити, що за замовчуванням він створює 2 файли одночасно на кожному ядрі процесора, і не дасть вам "чистий" минулий час, а абсолютний "користувальницький" час. Таким чином, всі синхросигнали вирівнюються між паралельними файлами і виглядають дуже схоже.

Щоб подолати це, встановіть -jobsпрапор на 1 , щоб він не паралелізував складання файлів. Це займе більше часу, але врешті-решт у вас буде "чистий" час компіляції, який ви можете порівнювати файл за файлом.

Це приклад команди, яка повинна виконати трюк:

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

Вихід фази "Compile Swift files" буде приблизно таким:

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

З цього виводу ви можете швидко визначити, на які файли потрібно більше часу, ніж на інші. Крім того, ви можете з високою точністю визначити, чи скорочуються ваші рефактори (явні ролики, підказки типу тощо) зменшують час компіляції для певних файлів чи ні.

ПРИМІТКА: технічно ви також можете це зробити, xcodebuildале результат неймовірно багатослівний і важкий для споживання.


1
Просто переконайтеся, що у вас для оптимізації цілого модуля проекту встановлено значення false, або він не відокремлює окремі швидкі файли.
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

Я розробив плагін Xcode, який може стати в нагоді для тих, хто відчуває ці проблеми.

зображення

Здається, що в Swift 3 вдосконалюються, тому, сподіваємось, ми побачимо, що наш код Swift швидше збирається.


Дивовижно, сподіваюся, я можу дати вам більше ніж +1. ти правдивий і твій плагін також чудовий. Я використовував це, і час моєї збірки зменшується, а це означає, що це дуже швидкий розвиток, тому що ця опція іноді кошмар і спричиняє сповільнення компілятора.
hardikdevios

Фантастичний! Ваш інструмент мені дуже допомагає. Спасибі
Філ

Чудовий плагін - Дійсно корисний! Спасибі
365SplendidSuns

@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 , інший греп не спрацює
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
ну так, це частина оптимізацій, які ви робите для покращення часу компіляції, але все ж основна проблема поточного швидкого компілятора полягає в тому, що він все ще перекомпілює все, що є одним швидким файлом кожного разу, коли ви робите найменші зміни.
apouche

4
Це було б смішно, якби не було так сумно.
Том Андерсен

15

Варто зазначити, що двигун виводу типу Swift може бути дуже повільним з вкладеними типами. Ви можете отримати загальне уявлення про те, що викликає повільність, переглянувши журнал збирання окремих блоків компіляції, які тривалий час, а потім скопіювати та вставити повну команду, породжену Xcode, у вікно терміналу, а потім натиснути CTRL- \, щоб отримати деяка діагностика. Погляньте на http://blog.impathic.com/post/99647568844/debugging-slow-swift-compile-times для повного прикладу.


Це для мене найкраща відповідь (див. Посилання). Я міг ЛЕГКО знайти дві різні лінії, які були проблемою, і вирішити її, розклавши мої лінії на більш дрібні.
Ніко

Це дуже корисна відповідь, оскільки вона показує, як знайти, де компілятор зійшов з розуму. У моєму випадку це було так: "curScore [curPlayer% 2] + curScore [2 + curPlayer% 2] == 3 && maker% 2 == curPlayer% 2" Щойно я перемістив його з "якщо" в " ", це призвело до того, що" вираз був занадто складним, щоб його можна було вирішити в розумний час; розглянути питання про розбиття виразу на окремі підвислови "
Дмитро

Це, безумовно, найбільш корисний спосіб вирішити цю проблему.
Річард Венебл

9

Також переконайтесь, що під час компіляції для налагодження (Swift або Objective-C) ви встановите лише Активна архітектура:

введіть тут опис зображення


6

Оскільки весь цей матеріал є в бета-версії, а оскільки компілятор Swift (принаймні станом на сьогодні) не відкритий, я думаю, що немає реального відповіді на ваше запитання.

Перш за все, порівняння компілятора Objective-C з Swift є якось жорстоким. Свіфт все ще в бета-версії, і я впевнений, що Apple працює над тим, щоб забезпечити функціональність та виправити помилки, більше ніж забезпечити швидкість блискавки (ви не починаєте будувати будинок, купуючи меблі). Я думаю, Apple вчасно оптимізує компілятор.

Якщо з якихось причин всі вихідні файли повинні бути скомпільовані повною мірою, можливим може бути створення окремих модулів / бібліотек. Але цей варіант ще не можливий, оскільки Swift не може дозволити бібліотеки, поки мова не є стабільною.

Я здогадуюсь, що вони оптимізують компілятор. З тієї ж причини, що ми не можемо створити попередньо складені модулі, цілком може бути, що компілятору потрібно зібрати все з нуля. Але як тільки мова досягне стабільної версії, а формат бінарних файлів більше не змінюється, ми зможемо створити наші бібліотеки, а можливо (?) Компілятор також зможе оптимізувати свою роботу.

Хоча лише здогадуватися, бо тільки Apple знає ...


"З тієї ж причини, що ми не можемо створити попередньо складені модулі, цілком може бути, що компілятору необхідно зібрати все з нуля." приємне спостереження, раніше не думав про це так.
чакрит

1
2017 рік і він все ще повільний
Педро Паулу Аморім

2017 з Xcode 9 та новою системою збірки та ще повільним
pableiros

2018 рік з Xcode 9, у мене є проект з 50+ швидкими файлами, якщо я роблю чисту збірку, зараз минуло 5 хвилин, і мою компіляцію ще не виконали.
Чень Лі Йонг

5

Для Xcode 8 перейдіть до налаштувань проекту, а потім Редактор> Додати налаштування збірки> Додати налаштування, визначені користувачем, та додайте наступне:

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

Якщо додати цей прапор, дивом ми збільшили час складання з 7 хв до 65с для проекту 40KLOC. Також можна підтвердити, що 2 друзі побачили подібні покращення у проекті підприємств.

Я можу лише припустити, що це якась помилка в Xcode 8.0

EDIT: Деякі люди, схоже, не працюють у Xcode 8.3.


2
Де, будь ласка, "налаштування проекту"?
Раніс

@Raniys Клацніть на синій значок на рівні кореня на лівій панелі Xcode.
Кріс

Я вважаю, що з Xcode 8.3 (не бета-версія) у моєму випадку це більше не працює :(
Кріс

4

На жаль, компілятор Swift все ще не оптимізований для швидкої та поступової компіляції (станом на Xcode 6.3 beta). Тим часом ви можете використовувати деякі з наступних методів, щоб поліпшити час компіляції Swift:

  • Розбийте додаток на рамки, щоб зменшити вплив на перекомпіляцію. Але майте на увазі, що ви повинні уникати циклічних залежностей у вашому додатку. Щоб отримати детальну інформацію про цю тему, перегляньте цю публікацію: http://bits.citrusbyte.com/improving-swift-compile-time/

  • Використовуйте Swift для частин вашого проекту, які є досить стабільними і не змінюються часто. Для інших областей, де потрібно дуже часто змінювати, або областей, які потребують великої кількості ітерацій компіляції / запуску, щоб бути завершеними (майже будь-які матеріали, що стосуються інтерфейсу), краще використовувати Objective-C із підходом поєднання та відповідності.

  • Спробуйте ввести код виконуваної програми за допомогою "Ін'єкції для Xcode"

  • Використовуйте метод roopc: http://roopc.net/posts/2014/speeding-up-swift-builds/

  • Увімкніть механізм швидкого виводу, даючи деякі підказки з чіткими кадрами.


4

Швидкі масиви та побудова словників, здається, є досить популярною причиною цього (спеціально для вас, хто походить з фона 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. Оптимізація всього модуля: НІ

Я витратив незліченну кількість годин, чекаючи, коли проект буде розроблений, щоб зрозуміти, що мені довелося внести цю невелику зміну, і мені довелося чекати цілих ще 30 хвилин, щоб перевірити її. Це налаштування, які працювали для мене. (Я все ще експериментую з налаштуваннями)

Але переконайтеся, що ви принаймні встановили "DWARF з dSYM" (якщо ви хочете відстежувати свою програму) та побудуйте активну архітектуру на "НІ", щоб випустити / архівувати, щоб перейти на iTunes Connect (я пам’ятаю, що витрачав тут і кілька годин).


4
Я можу помилятися, але чи не встановлення підвищених рівнів оптимізації фактично не збільшить час збирання? Рівні оптимізації покращать продуктивність виконання.
Водоспад Майкл

1
Set Build for Active Architecture: YESдав мені приблизно на 45% скорочення часу на компіляцію. Велика подяка
Жан Ле Мойнан

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може представляти багато різних числових типів. Отже, компілятору потрібно з'ясувати з контексту, який це.

+Також слід уникати функцій, які потребують багато часу для пошуку . Використання декількох +для об'єднання декількох масивів є повільним, оскільки компілятору необхідно визначити, яку реалізацію +слід викликати для кожного +. Тому використовуйте avar a: [Foo] з append()замість цього , якщо це можливо.

Ви можете додати попередження, щоб визначити, які функції повільно збирати в Xcode .

У Налаштуваннях збірки для цільового пошуку інших прапорів Swift та додайте

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

попереджати про кожну функцію, яка займає більше 100 мс для складання.


4

Для проектів , які змішуються Objective-C і Swift код, ми можемо встановити -enable-bridging-pchв Other Swift Flags. За допомогою цього мостовий заголовок аналізується лише один раз, а результат (тимчасовий «попередньо складений заголовок» або «PCH» файл) кешується та повторно використовується для всіх файлів Swift у цілі. Apple заявила, що скорочує час складання на 30%. Посилання:

ПРИМІТКА. Це працює лише для Swift 3.1 і вище.


2

Перезавантаження мого Mac творило чудеса для цього питання. Я перейшов від 15-хвилинних збірок до 30-ти секундних версій лише перезавантаженням.


1

Швидкий час компіляції було покращено в новому Xcode 6.3

Удосконалення компілятора

Компілятор Swift 1.2 був розроблений для більш стабільної та всілякої поліпшення продуктивності. Ці зміни також забезпечують кращий досвід роботи зі Swift у Xcode. Деякі з найбільш помітних поліпшень включають:

Поступові нарощування

Файли, які не були змінені, більше не будуть перекомпільовані за замовчуванням, що значно покращить час збирання для більшості поширених випадків. Більш масштабні структурні зміни вашого коду все ще можуть вимагати відновлення кількох файлів.

Швидше виконання файлів

Налагодження налагодження створюють бінарні файли, які працюють значно швидше, а нові оптимізації забезпечують ще кращу ефективність збірки версій.

Краща діагностика компілятора

Чіткіші повідомлення про помилки та попередження, а також нові Fix-його полегшують написання належного коду Swift 1.2.

Підвищення стабільності

Виправлені найпоширеніші збої компілятора. Ви також повинні побачити менше попереджень SourceKit в редакторі Xcode.


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 . Це скоротило час складання до 3 хвилин з 10 хвилин.

Там написано, що слід увімкнути Whole Module Optimization час додавання -Ononeв Other Swift Flags.

Я використовую Swift 3на Xcode 8.3/Xcode 8.2 .


0

Змішування цілочислового прямого і прямолінійного літералу в одному виразі також спричиняє тривалий час компіляції.

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

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

Багато висловлювань часу компіляції 1000 + мс скорочуються до 10 ~ 100 мс після того, як я ставлю .0після цілого літералу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.