Подтвердить что ты не робот

Swift WHOLE_MODULE_OPTIMIZATION улучшает время компиляции, но вызывает сбой lldb/Xcode

TL; DR

До

SWIFT_WHOLE_MODULE_OPTIMIZATION = NO

  • Отладка компиляции занимает 10-15 минут.
  • Снятие компиляции занимает 25 минут
  • po отлично работает в LLDB

После

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

  • Отладка компиляции занимает 1-2 минуты.
  • Снятие компиляции занимает ~ 8 минут
  • po всегда приводит к сбою Xcode.

Любая идея, почему ужасное время компиляции основано на этой информации и/или почему Xcode может сбой?


Deets

Я работаю над большим 100-процентным проектом Swift (в Objective-C есть сторонние библиотеки, но весь наш код - Swift). У нас были ужасные времена компиляции, обычно около 10-15 минут, чтобы скомпилировать конфигурацию отладки и 30 минут для компиляции конфигурации выпуска.

С этим проектом было очень сложно работать из-за ужасного времени компиляции. Я искал способы улучшить это, особенно через настройки сборки, и в течение нескольких месяцев не повезло. Одна вещь, которую я упускал из виду, был SWIFT_WHOLE_MODULE_OPTIMIZATION, особенно потому, что любое упоминание об этом утверждает, что это увеличит время компиляции проекта.

Итак, на днях мы включили SWIFT_WHOLE_MODULE_OPTIMIZATION, и вот и у нас есть 10-кратное улучшение во время компиляции.

Проблема в том, что теперь, когда мы отлаживаем проект и пытаемся распечатать объект в lldb с помощью po myObject, Xcode сразу же сбой. Вот некоторая информация из журнала сбоев:

Процесс: Xcode [5860]
Путь:/Applications/Xcode.app/Contents/MacOS/Xcode
Идентификатор: com.apple.dt.Xcode
Версия: 6.4 (7720)
Информация о сборке: IDEFrameworks-7720000000000000 ~ 8
Идентификационный номер товара: 497799835
Приложение Внешний ID: 812725084
Тип кода: X86-64 (родной)
Родительский процесс:??? [1]
Ответственный: Xcode [5860]

Дата/время: 2015-08-05 15: 53: 08.265 -0600
Версия ОС: Mac OS X 10.11 (15A235d)
Версия отчета: 11

Время пробуждения с момента загрузки: 13000 секунд

Сбитая тема: 20

Тип исключения: EXC_BAD_ACCESS (SIGSEGV)
Коды исключений: KERN_INVALID_ADDRESS на 0x000000000000008f
Замечание об исключении: EXC_CORPSE_NOTIFY

Области VM Около 0x8f: →     __TEXT 000000010ef62000-000000010ef63000 [4K] r-x/rwx SM = COW/Applications/Xcode.app/Contents/MacOS/Xcode

Информация о приложении:
ProductBuildVersion: 6E35b

Здесь трассировка стека на разбитой теме:

Thread 20 Crashed:: <DBGLLDBSessionThread (pid=6402)>
0   com.apple.LLDB.framework        0x0000000116b09ab4 swift::ArchetypeBuilder::resolveArchetype(swift::Type) + 68
1   com.apple.LLDB.framework        0x0000000116b0f808 std::__1::__function::__func<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6, std::__1::allocator<substConcreteTypesForDependentTypes(swift::ArchetypeBuilder&, swift::Type)::$_6>, swift::Type (swift::Type)>::operator()(swift::Type&&) + 152
2   com.apple.LLDB.framework        0x0000000116bc0986 swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 54
3   com.apple.LLDB.framework        0x0000000116bc0f2b swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 1499
4   com.apple.LLDB.framework        0x0000000116bc0bbb swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 619
5   com.apple.LLDB.framework        0x0000000116bc0c0a swift::Type::transform(std::__1::function<swift::Type (swift::Type)> const&) const + 698
6   com.apple.LLDB.framework        0x0000000116b0c8f2 swift::ArchetypeBuilder::substDependentType(swift::Type) + 50
7   com.apple.LLDB.framework        0x0000000116e9554e (anonymous namespace)::LowerType::visitAnyStructType(swift::CanType, swift::StructDecl*) + 270
8   com.apple.LLDB.framework        0x0000000116e92e66 swift::Lowering::TypeConverter::getTypeLoweringForUncachedLoweredType(swift::Lowering::TypeConverter::TypeKey) + 150
9   com.apple.LLDB.framework        0x0000000116e92b39 swift::Lowering::TypeConverter::getTypeLowering(swift::Lowering::AbstractionPattern, swift::Type, unsigned int) + 2361
10  com.apple.LLDB.framework        0x0000000116f8f711 lldb_private::SwiftSILManipulator::emitLValueForVariable(swift::VarDecl*, lldb_private::SwiftExpressionParser::SILVariableInfo&) + 1521
11  com.apple.LLDB.framework        0x00000001172ac7ee (anonymous namespace)::LLDBNameLookup::emitLValueForVariable(swift::VarDecl*, swift::SILBuilder&) + 102
12  com.apple.LLDB.framework        0x0000000116ebb162 swift::Lowering::SILGenFunction::emitInitializationForVarDecl(swift::VarDecl*, swift::Type) + 98
13  com.apple.LLDB.framework        0x0000000116ebbc74 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 404
14  com.apple.LLDB.framework        0x0000000116ebbc57 swift::ASTVisitor<(anonymous namespace)::InitializationForPattern, void, void, void, std::__1::unique_ptr<swift::Lowering::Initialization, std::__1::default_delete<swift::Lowering::Initialization> >, void, void>::visit(swift::Pattern*) + 375
15  com.apple.LLDB.framework        0x0000000116ebba0d swift::Lowering::SILGenFunction::visitPatternBindingDecl(swift::PatternBindingDecl*) + 45
16  com.apple.LLDB.framework        0x0000000116f0617c swift::Lowering::SILGenFunction::visitBraceStmt(swift::BraceStmt*) + 284
17  com.apple.LLDB.framework        0x0000000116ecd1c0 swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 320
18  com.apple.LLDB.framework        0x0000000116ea3966 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 246
19  com.apple.LLDB.framework        0x0000000116ea3828 swift::Lowering::SILGenModule::visitFuncDecl(swift::FuncDecl*) + 168
20  com.apple.LLDB.framework        0x0000000116ea579b swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 427
21  com.apple.LLDB.framework        0x0000000116ea5c22 swift::SILModule::constructSIL(swift::Module*, swift::SILOptions&, swift::SourceFile*, llvm::Optional<unsigned int>, bool, bool) + 386
22  com.apple.LLDB.framework        0x0000000116ea5d42 swift::performSILGeneration(swift::SourceFile&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 98
23  com.apple.LLDB.framework        0x00000001172aa617 lldb_private::SwiftExpressionParser::Parse(lldb_private::Stream&, unsigned int, unsigned int, unsigned int) + 10715
24  com.apple.LLDB.framework        0x000000011706b3e8 lldb_private::ClangUserExpression::Parse(lldb_private::Stream&, lldb_private::ExecutionContext&, lldb_private::ExecutionPolicy, bool, unsigned int) + 1064
25  com.apple.LLDB.framework        0x000000011706cdb4 lldb_private::ClangUserExpression::Evaluate(lldb_private::ExecutionContext&, lldb_private::EvaluateExpressionOptions const&, char const*, char const*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::Error&, unsigned int, std::__1::shared_ptr<lldb_private::Module>*) + 628
26  com.apple.LLDB.framework        0x00000001171d1696 lldb_private::Target::EvaluateExpression(char const*, lldb_private::StackFrame*, lldb_private::SharingPtr<lldb_private::ValueObject>&, lldb_private::EvaluateExpressionOptions const&) + 376
27  com.apple.LLDB.framework        0x000000011716d75c lldb_private::SwiftLanguageRuntime::GetObjectDescription(lldb_private::Stream&, lldb_private::ValueObject&) + 668
28  com.apple.LLDB.framework        0x00000001170464e6 lldb_private::ValueObject::GetObjectDescription() + 370
29  com.apple.LLDB.framework        0x000000011548e228 lldb::SBValue::GetObjectDescription() + 76
30  com.apple.dt.dbg.DebuggerLLDB   0x00000001153f3c9e -[DBGLLDBDataValue _lldbValueObjectDescription] + 24
31  com.apple.dt.dbg.DebuggerLLDB   0x00000001153f3b7f -[DBGLLDBDataValue lldbDescription] + 29
32  com.apple.dt.dbg.DebuggerLLDB   0x00000001154023dc __87-[DBGLLDBSession printDescriptionOfDataValueToConsole:runAllThreads:completionHandler:]_block_invoke + 182
33  com.apple.dt.dbg.DebuggerLLDB   0x0000000115402e6d -[DBGLLDBSession handleNextActionWithState:withRunPending:] + 424
34  com.apple.dt.dbg.DebuggerLLDB   0x00000001153fdf44 DBGLLDBSessionThread(void*) + 980
35  libsystem_pthread.dylib         0x00007fff8ec12cb3 _pthread_body + 131
36  libsystem_pthread.dylib         0x00007fff8ec12c30 _pthread_start + 168
37  libsystem_pthread.dylib         0x00007fff8ec10419 thread_start + 13

Похоже, мы можем быть на переднем крае новой технологии, потому что я пока не нашел большой помощи в этой проблеме. Мне интересно, есть ли у нас какая-то необычная конфигурация, вызывающая проблемы времени компиляции, или если есть известная причина, по которой lldb может быть сбой. Это то же самое на нескольких разных машинах, с El Capitan, Yosemite, Xcode 6.3, Xcode 6.4. Любая помощь приветствуется!

4b9b3361

Ответ 1

Я работал, и я активно работаю над проектами, которые, вероятно, даже больше, чем ваши (более 50 библиотек, сотни пользовательских классов с тысячами LoC). Требуется несколько секунд для компиляции и до 2 минут для создания релиза (LAT 2013 MBP), даже для полного проекта Swift.

Я бы настоятельно рекомендовал искать другие причины, так как этот параметр говорит вам, что ваша проблема находится где-то еще, так как это влияет на производительность приложения, а не на скорость создания. Возможно, у вас есть ваш .pch файл, полный материала, который там не принадлежит или что-то в этом роде, он может вызвать такое замедление.

Другая интересная вещь - использование вывода. Я лично объявляю тип для каждой отдельной переменной только потому, что ее легче читать для других, но есть еще кое-что. Поскольку вывод может усложниться, он может заставить компилятор занять много времени, чтобы выяснить, что на самом деле делает ваш код. Прочтите эту примерную статью, хотя это больше похоже на альфа-проблему. НО МОГУТ, может быть, у вас есть что-то подобное в вашем коде. Что бы стоило сделать, это попытаться удалить весь быстрый код, скомпилировать библиотеки, если это хорошо работает, тогда вы знаете, что проблема в вашем быстром коде и, вероятно, будет связана с этим.

Кроме того, если вы предоставляете WHAT, на самом деле замедляет время сборки (потому что вы можете видеть весь процесс сборки с отметками времени, и существует высокая вероятность того, что один шаг просто займет навсегда), это может помочь точно определить проблему.

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

Изменить: Еще одна статья по этой интересной теме

Ответ 2

Мне удалось исправить это в нашем проекте. (Общее время компиляции 12 минут)

Ключ должен установить SWIFT_WHOLE_MODULE_OPTIMIZATION = YES, как вы говорите, в настройках user defined

Но вам нужно сделать еще одно изменение. Вам нужно установить уровень оптимизации None в debug, иначе вы не сможете отлаживать свое приложение.

Я написал сообщение в блоге об этом здесь:

https://tech.zalando.com/blog/improving-swift-compilation-times-from-12-to-2-minutes/