Xcode 6 со Swift супер медленной печатью и автозаполнением
Это просто я или Xcode 6 (6.0.1) с Swift, кажется, очень медленный, когда вы печатаете свой код, особенно с автозаполнением?
Обычный класс Objective-C, даже если он находится внутри проекта Swift, работает почти так же, как и раньше, поэтому его убивает Swift.
Кто-нибудь еще испытывает такое же неудобство? У вас есть идеи, как улучшить производительность?
- Я пытался играть с некоторыми настройками, но не повезло.
- Я также, конечно, безуспешно пытался перезапустить Xcode и компьютер.
- Другие тяжелые приложения не открыты.
Я использую Macbook Pro середины 2009 года (Intel Core 2 Duo с частотой 2,26 ГГц) с 8 ГБ ОЗУ и твердотельным накопителем HD, что не является чем-то новым, но все же не полным мусором.
Это позор, так как я был взволнован, чтобы начать использовать Swift, и теперь это действительно невыносимо.
Мысли / советы?
11 ответов
- Выйти из Xcode и перезагрузить Mac не обязательно, но желательно.
- Удалить содержимое папки ~ / Библиотека / Разработчик / Xcode / DerivedData
- Удалить содержимое ~ / Library / Caches / com.apple.dt.Xcode
Это временное решение, но оно отлично работает.
Ниже сценария с помощью приложения Script Editor.
tell application "Terminal"
do script "rm -frd ~/Library/Developer/Xcode/DerivedData/*"
do script "rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"
end tell
Кроме того, вы можете создать псевдоним для вашего терминала, например:
alias xcodeclean="rm -frd ~/Library/Developer/Xcode/DerivedData/* && rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"
Вы можете добавить это к вашему ~/.bash_profile
а затем введите xcodeclean
в командной строке каждый раз, когда вы хотите очистить эти две папки.
Я также испытал 100%+ процессор при наборе "простого" кода. Несколько небольших хитростей для ускорения работы swift-parser в процессе структурирования кода.
Не используйте конкатинатор "+" в строках. Для меня это вызывает медлительность очень быстро. Каждое новое "+" приводит к сканированию синтаксического анализатора, и он должен повторно анализировать код каждый раз, когда вы добавляете новый символ где-то в теле функции.
Вместо:
var str = "This" + String(myArray.count) + " is " + String(someVar)
Используйте синтаксис шаблона, который кажется более эффективным для анализа в swift:
var str = "This \(myArray.count) is \(someVar)"
Таким образом, я в основном не замечаю никаких ограничений в строковых переменных "\(*)" .
Если у вас есть расчеты, которые используют + / * - разделите их на более мелкие части.
Вместо:
var result = pi * 2 * radius
использовать:
var result = pi * 2
result *= radius
Это может выглядеть менее эффективно, но быстрый синтаксический анализатор в этом случае намного быстрее. Некоторые формулы не будут компилироваться, если им нужно много операций, даже если они математически верны.
Если у вас есть какие-то сложные вычисления, поместите их в функцию. Таким образом, синтаксический анализатор может анализировать его один раз, и ему не нужно повторять его каждый раз, когда вы что-то меняете в теле функции.
Потому что, если у вас есть вычисление в теле функции, то каким-то образом быстрый анализатор проверяет его каждый раз, если типы, синтаксис и т. Д. Все еще верны. Если линия превысит вычисление, то некоторые переменные внутри вашего вычисления / формулы могут измениться. Если вы поместите его во внешнюю функцию, то он будет проверен один раз, и swift будет рад, что он будет корректным и не будет повторно анализировать его постоянно, что вызывает высокую загрузку ЦП.
Таким образом, я набрал от 100% при каждом нажатии клавиши до низкой загрузки процессора во время набора текста. Например, эти 3 строки, вставленные в ваше тело функции, могут привести к быстрому сканированию.
let fullPath = "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData = NSDictionary(contentsOfFile: fullPath )! // as Dictionary<String, AnyObject>
let spaces : AnyObject = spacesData["SpacesDisplayConfiguration"]!["Management Data"]!!["Monitors"]!![0]["Spaces"]!!
println ( spaces )
но если я положу его в func и позвоню позже, swiftparser будет намного быстрее
// some crazy typecasting here to silence the parser
// Autodetect of Type from Plist is very rudimentary,
// so you have to teach swift your types
// i hope this will get improved in swift in future
// would be much easier if one had a xpath filter with
// spacesData.getxpath( "SpacesDisplayConfiguration/Management Data/Monitors/0/Spaces" ) as Array<*>
// and xcode could detect type from the plist automatically
// maybe somebody can show me a more efficient way to do it
// again to make it nice for the swift parser, many vars and small statements
func getSpacesDataFromPlist() -> Array<Dictionary<String, AnyObject>> {
let fullPath = "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData = NSDictionary(contentsOfFile: fullPath )! as Dictionary<String, AnyObject>
let sdconfig = spacesData["SpacesDisplayConfiguration"] as Dictionary<String, AnyObject>
let mandata = sdconfig["Management Data"] as Dictionary<String, AnyObject>
let monitors = mandata["Monitors"] as Array<Dictionary<String, AnyObject>>
let monitor = monitors[0] as Dictionary<String, AnyObject>
let spaces = monitor["Spaces"] as Array<Dictionary<String, AnyObject>>
return spaces
}
func awakeFromNib() {
....
... typing here ...
let spaces = self.getSpacesDataFromPlist()
println( spaces)
}
Swift и XCode 6.1 все еще очень глючные, но если вы будете следовать этим простым приемам, редактирование кода снова станет приемлемым. Я предпочитаю swift много, так как он избавляется от файлов.h и использует намного более чистый синтаксис. По-прежнему требуется много приведений типов, например "myVar as AnyObject", но это меньшее зло по сравнению со сложной структурой и синтаксисом проекта target-c.
Кроме того, я попробовал SpriteKit, который интересно использовать, но он довольно неэффективен, если вам не нужна постоянная перекраска со скоростью 60 кадров в секунду. Использование старых CALayers намного лучше для процессора, если ваши "спрайты" меняются не так часто. Если вы не измените.contents слоев, тогда CPU в основном простаивает, но если у вас приложение SpriteKit, работающее в фоновом режиме, то воспроизведение видео в других приложениях может заикаться из-за жесткого цикла обновления 60fps.
Иногда xcode выдает странные ошибки при компиляции, тогда это помогает перейти в меню "Product > Clean" и скомпилировать его снова, что является ошибочной реализацией кеша.
Другой отличный способ улучшить синтаксический анализ, когда xcode застревает в вашем коде, упоминается в другом посте stackru здесь. По сути, вы копируете все содержимое файла.swift во внешний редактор, а затем по функциям копируете его обратно и видите, где находится ваше узкое место. Это фактически помогло мне снова получить xcode с разумной скоростью, после того, как мой проект сошел с ума со 100% CPU. копируя ваш код обратно, вы можете реорганизовать его и попытаться сделать ваши функциональные тела короткими, а функции / формулы / выражения простыми (или разбить на несколько строк).
Автозаполнение не работает после Xcode 4. Пока Apple не решит исправить эту 2-летнюю ошибку, к сожалению, единственное решение - отключить завершение кода в настройках XCode (первый вариант на рисунке ниже).
Вы можете продолжить наслаждаться завершением вручную, набрав CTRL space
или же ESC
когда тебе это нужно.
Это единственное решение, которое работает каждый раз в 100% случаев.
Недавно я обнаружил еще одну вещь: если вы используете плагины в Xcode, не делайте этого. Убери их всех. Они усугубляют проблему.
Вы используете Spotify? Я установил Yosemite GM с Xcode 6.1 GM на iMac в середине 2009 года (2,66 ГГц) с той же проблемой. Я обнаружил, что процесс с именем "SpotifyWebHelper" всегда помечается красным, как не отвечающий, поэтому я отключил опцию "начать с веб" в Spotify и теперь XCode, кажется, работает значительно лучше.
У меня были такие же проблемы даже в Xcode 6.3
- супер медленные автодополнения
- супер медленная индексация
- огромное использование процессора swift и SourceKitService
- огромное использование памяти SourceKitService
Все это происходило даже в относительно небольших проектах. Я перепробовал все исправления, которые смог найти:
- удаление ~/ Библиотека / Разработчик /Xcode/DerivedData/*
- удаление ~/Library/Caches/com.apple.dt.Xcode/*
- удалить все "+" объединения строк из кода
- убрал все подозрительные словарные объявления
Ничто из этого не помогло в моем проекте.
Что на самом деле решило мою проблему:
- помещая каждый конец каждого класса в свой собственный файл
- размещение каждого расширения в своем собственном файле (Class+ExtName.swift)
- размещение "вне класса быстрых методов" в своем собственном файле
Теперь у меня практически нулевое использование процессора, низкое использование памяти и довольно быстрое завершение работы.
Как правило, перемещение папки кэша (DerivedData) на SSD-диск (особенно в моем случае - внешнее хранилище, подключенное к выходу Thunderbolt) значительно улучшило мою производительность Xcode. Время компиляции и общие вопросы вокруг приложения примерно в 10 раз быстрее. Также перемещена вся папка git на SSD, что значительно улучшило производительность git.
Свертывание всех методов мало помогает.
Команда-Alt-Shift-стрелка влево будет добиваться цели...
Чтобы сложить / развернуть текущие методы или если структуры используют:
Сложите: команда-Alt-стрелка влево
Развернуть: команда-Alt-стрелка вправо
Я узнал, что обычно происходит, когда вы:
- иметь длинные выражения в одном выражении (см. этот ответ)
- смешать несколько пользовательских операторов в одном выражении
Второй случай, кажется, исправлен в одном из последних выпусков xcode. Пример: я определил 2 пользовательских оператора <&&> и <||>и использовал их в выражении типа a <&&> b <&&> c <||> d
, Разделение на несколько строк решило проблему:
let r1 = a <&&> b
let r2 = r1 <&&> c
let r3 = r2 <||> d
Я надеюсь, что ваши дела покрываются одним из 2 выше... пожалуйста, оставьте комментарий в любом случае
Это была боль до XCode 7.2.
Apple исправила это в XCode 7.3, и теперь это работает как шарм. Он очень быстрый и намного более мощный, так как кажется, что он работает как нечеткий поиск файлов: вам не нужно вводить точное начало метода / свойства, чтобы оно появилось в списке предложений.
SourceKitService
также немного неудобно иметь дело с комментариями в коде, а встроенные комментарии также замедляют его.
так что, если вы можете позволить себе убрать массивное пятно встроенных комментариев, например:
/*
* comment
/*
* embedded comment
*/
*/
это определенно может помочь.
ПРИМЕЧАНИЕ: в моем случае мой Xcode 7.3.1 (7D1014) был буквально заблокирован, и я печатал любое письмо, когда в файле было около 700 строк комментариев со встроенными комментариями. Первоначально я удалил этот блок из этого.swift
файл и Xcode снова стали живыми. Я пытался добавлять свои комментарии обратно по частям, удаляя встроенные комментарии, они все еще были медленнее, чем обычно, но показали значительно лучшую производительность, если не было встроенных комментариев.
У меня была та же проблема, когда типирование запаздывало в определенном классе и оказалось, что
/*
Long
multiline
comments
*/
замедлял набор текста.