Xcode 8 очень медленная компиляция Swift

Со времен Swift 3 и Xcode 8 мой проект компилируется довольно медленно. Каждый раз, когда я добавляю в файл пустую строку, перекомпиляция занимает целую минуту. Когда я проверяю вывод, нет конкретного файла, который занимает очень много времени. (Я также использовал этот инструмент для измерения: https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode)

Всегда получается скомпилировать 4 файла одновременно. "Ритм" довольно устойчивый. Просто очень медленно...

Кроме того: всякий раз, когда я открываю файлы или переключаюсь между ними, процесс автозаполнения или появления ошибок/предупреждений может занять очень много времени.

Какие вещи я могу проверить? Я почти чувствую, что есть какой-то флаг, который я устанавливаю, который просто снижает скорость сборки как сумасшедший.

РЕДАКТИРОВАТЬ: Это не решение основной проблемы, но я потратил некоторое время на перенос больше кода в каркасы. Это имело значение (просто потому, что каждый раз приходится перекомпилировать меньше файлов). Это не должно быть необходимым, но это стало невыносимо... Я, конечно, все еще очень ищу правильное решение.

Ответ 1

Проблема с этой проблемой заключается в том, что мы не знаем, где неправильная инициализация/декларация. Решение, которое предлагает мой коллега, состоит в том, чтобы найти, какая функция занимает много времени, чтобы скомпилировать так:

  • Перейдите к Project выберите цель
  • Build SettingsSwift Compiler - Custom Flags
  • Добавить в Other Swift Flags -Xfrontend -warn-long-function-bodies=50 (50 представляет время в миллисекундах)

после этого должно появиться следующее предупреждение:

Getter 'frameDescription' занял 108 мс для проверки типа (ограничение: 50 мс)

и после этого вы знаете, что делать;)

Ответ 2

У меня была такая же проблема только с момента обновления до Swift 3/XCode 8, и, похоже, это вызвано большими литералами массивов, аналогичными этим.

Мне удалось исправить проблему, добавив аннотации типов к переменным, назначаемым литералу массива, например.

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

вместо

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

Ответ 3

Это проблема с Xcode 8, где он не выполняет инкрементные сборки правильно. Если вы редактируете один быстрый файл, он должен скомпилировать только этот файл. Это уже было сказано здесь: Xcode 8 полностью перестраивает проект

4 файла за один раз строятся так, как Xcode выполняет полную перестройку проекта, которая не должна повторяться, если вы только изменили одну строку в одном файле.

Ответ 4

В моем случае я использовал вспомогательную функцию для сохранения некоторых данных в Firebase. Эта функция возвращала словарь с примерно 20 элементами, и для компиляции потребовалось около 40 минут. Мое решение состояло в том, чтобы инициализировать пустой словарь, а затем добавить элементы один за другим до 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
}

Ответ 5

Это работало для меня по одному из моих проектов.

Перейдите в раздел Product → Scheme → Edit Scheme. Выберите "Сборка" в левой части и снимите флажок "Найти неявные зависимости". Но этот флаг должен остаются проверенными, когда вы строите проект в первый раз.

Источник

Это был простой проект, и он увеличил один из моих построек с 1 минуты до 2 секунд.

На физическом устройстве я получил эти результаты. Для одного из моих больших проектов (42 файла) только уменьшилось его с 2:36 до 2:20. Затем я добавил: SWIFT_WHOLE_MODULE_OPTIMIZATION = YES для создания настроек в качестве пользовательской настройки. Время дошло до - 2:00

В симуляторе сборка составляла 49 секунд в первый раз, когда я использовал.

Перейдите в раздел Product → Scheme → Edit Scheme. Выберите "Сборка" в левой части и снимите флажок "Найти неявные зависимости". Но этот флаг должен остаются проверенными, когда вы строите проект в первый раз.

а сборка заняла 7 секунд.

Надеюсь, это поможет.

Ответ 6

Я смог значительно сократить время быстрой компиляции проекта, избегая использования оператора Nil-Coalescing и конкатенации строк.

В других словах, где у меня было что-то вроде:

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

Я изменил его на

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

Мое время компиляции резко сократилось - от 20 минут до 20 секунд.

Ответ 7

Убедитесь, что вы не объединяете массивы типа let combinedArrays = array1 + array2. Там известная ошибка также для вывода типа здесь, где Swift тратит время на то, чтобы выяснить, какой тип должен быть combinedArrays. Вместо этого [array1, array2].joined() должен работать так же хорошо и компилироваться намного быстрее.

Ответ 8

Одна распространенная практика, которая замедляет время компиляции, заключается в использовании Array.append и String.append (или их эквивалентов оператора +). Для String s лучше использовать форматированную строку, поэтому вместо

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

вы должны использовать

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

Я не помню точного ускорения, но для этих линий это было порядка 10 раз. Скорее всего, есть вероятность, что это не будет иметь заметного ускорения для любых, но самых маленьких проектов. Например, в нашем проекте есть сотни файлов Swift, а также многие Objective-C, а время компиляции часто составляет 10 минут и более, иногда даже когда единственным изменением был файл без Swift.