Por que o tempo de compilação Swift é tão lento?


209

Estou usando o Xcode 6 Beta 6.

Isso é algo que me incomoda há algum tempo agora, mas está chegando a um ponto em que dificilmente pode ser usado agora.

Meu projeto está começando a ter um tamanho decente de 65 arquivos Swift e alguns arquivos Objective-C em ponte (que realmente não são a causa do problema).

Parece que qualquer pequena modificação em qualquer arquivo Swift (como adicionar um espaço em branco simples em uma classe que mal é usada no aplicativo) fará com que todos os arquivos Swift do destino especificado sejam recompilados.

Após uma investigação mais profunda, descobri que o que está consumindo praticamente 100% do tempo do compilador é a CompileSwiftfase em que o Xcode executa o swiftccomando em todos os arquivos Swift do seu destino.

Eu fiz algumas investigações adicionais e, se eu mantiver o aplicativo delegado apenas com um controlador padrão, a compilação é muito rápida, mas como eu estava adicionando mais e mais dos meus arquivos de projeto, o tempo de compilação estava começando a ficar muito lento.

Agora, com apenas 65 arquivos de origem, leva cerca de 8/10 segundos para compilar a cada vez. Não é muito rápido .

Eu não vi nenhum post falando sobre esse problema, exceto este , mas era uma versão antiga do Xcode 6. Então, estou me perguntando se sou o único nesse caso.

ATUALIZAR

Eu verifiquei alguns projetos Swift no GitHub como Alamofire , Euler e CryptoSwift , mas nenhum deles tinha arquivos Swift suficientes para comparar. O único projeto que achei que estava começando um tamanho decente foi o SwiftHN e, embora tivesse apenas uma dúzia de arquivos de origem, ainda era possível verificar a mesma coisa, um espaço simples e todo o projeto precisavam de recompilação, que estava começando a demorar um pouco. pouco tempo (2/3 segundos).

Comparado com o código Objective-C, onde o analisador e a compilação são rápidos, parece que o Swift nunca será capaz de lidar com grandes projetos, mas, por favor, me diga que estou errado.

ATUALIZAÇÃO Com o Xcode 6 Beta 7

Ainda não houve nenhuma melhoria. Isso está começando a ficar ridículo. Com a falta de #importSwift, eu realmente não vejo como a Apple poderá otimizar isso.

ATUALIZAÇÃO Com o Xcode 6.3 e o Swift 1.2

A Apple adicionou compilações incrementais (e muitas outras otimizações do compilador). Você precisa migrar seu código para o Swift 1.2 para ver esses benefícios, mas a Apple adicionou uma ferramenta no Xcode 6.3 para ajudá-lo:

Digite a descrição da imagem aqui

CONTUDO

Não se alegrem muito rápido como eu. O solucionador de gráficos que eles usam para tornar a construção incremental ainda não está muito otimizado.

De fato, primeiro, ele não considera as alterações de assinatura de função; portanto, se você adicionar um espaço no bloco de um método, todos os arquivos, dependendo dessa classe, serão recompilados.

Segundo, parece criar a árvore com base nos arquivos que foram recompilados, mesmo que uma alteração não os afete. Por exemplo, se você mover essas três classes para arquivos diferentes

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

Agora, se você modificar FileA, o compilador obviamente marcará FileAcomo recompilado. Também recompilará FileB(isso seria bom com base nas alterações de FileA), mas também FileCporque FileBé recompilado, e isso é muito ruim porque FileCnunca é usado FileAaqui.

Espero que eles melhorem o solucionador de árvores de dependência ... Abri um radar com esse código de exemplo.

ATUALIZAÇÃO Com Xcode 7 beta 5 e Swift 2.0

Ontem a Apple lançou o beta 5 e dentro das notas de lançamento pudemos ver:

Swift Language & Compiler • Compilações incrementais: alterar apenas o corpo de uma função não deve mais fazer com que os arquivos dependentes sejam reconstruídos. (15352929)

Eu tentei e devo dizer que está funcionando muito (realmente!) Bem agora. Eles otimizaram muito as construções incrementais rapidamente.

Eu recomendo que você crie uma swift2.0ramificação e mantenha seu código atualizado usando o XCode 7 beta 5. Você ficará satisfeito com os aprimoramentos do compilador (no entanto, eu diria que o estado global do XCode 7 ainda é lento e com erros)

ATUALIZAÇÃO Com o Xcode 8.2

Já faz um tempo desde a minha última atualização sobre esse problema, então aqui está.

Nosso aplicativo agora tem cerca de 20 mil linhas de código Swift quase exclusivamente, o que é decente, mas não excepcional. Foi submetido à migração rápida 2 e à migração rápida 3. Demora cerca de 5 / 6m para compilar em um Macbook pro de meados de 2014 (Intel Core i7 a 2,5 GHz), o que é bom em uma construção limpa.

No entanto, a construção incremental ainda é uma piada, apesar da Apple alegar que:

O Xcode não reconstruirá um destino inteiro quando apenas pequenas alterações ocorrerem. (28892475)

Obviamente, acho que muitos de nós rimos depois de verificar essa bobagem (adicionar uma propriedade privada (privada!) A qualquer arquivo do meu projeto recompilará a coisa toda ...)

Gostaria de apontar para este tópico nos fóruns de desenvolvedores da Apple, que têm mais algumas informações sobre o problema (além de apreciar a comunicação do desenvolvedor da Apple sobre o assunto de vez em quando)

Basicamente, as pessoas sugerem algumas coisas para tentar melhorar a construção incremental:

  1. Adicione uma HEADER_MAP_USES_VFSconfiguração de projeto definida comotrue
  2. Desativar Find implicit dependenciesdo seu esquema
  3. Crie um novo projeto e mova sua hierarquia de arquivos para o novo.

Vou tentar a solução 3, mas a solução 1/2 não funcionou para nós.

O que é ironicamente engraçado em toda essa situação é que, olhando para o primeiro post sobre esse problema, estávamos usando o Xcode 6 com o código swift 1 ou swift 1.1 quando atingimos a lentidão das primeiras compilações e agora cerca de dois anos depois, apesar das melhorias reais da Apple. situação é tão ruim quanto era com o Xcode 6. Que irônico.

Na verdade, eu realmente se arrepender de escolher Swift sobre Obj / C para o nosso projeto por causa da frustração diária que envolve. (Eu até mudo para o AppCode, mas isso é outra história)

De qualquer forma, vejo este post de SO com 32k + visualizações e 143 ups até o momento em que escrevi, então acho que não sou o único. Aguente firme, apesar de serem pessimistas com relação a essa situação, pode haver alguma luz no fim do túnel.

Se você tiver tempo (e coragem!), Acho que a Apple agradece o radar sobre isso.

Até a próxima! Felicidades

ATUALIZAÇÃO Com o Xcode 9

Tropeçar nisso hoje. O Xcode introduziu discretamente um novo sistema de compilação para melhorar o desempenho terrível atual. Você deve habilitá-lo através das configurações da área de trabalho.

insira a descrição da imagem aqui

Ainda tentei, mas atualizará esta postagem depois que ela terminar. Parece promissor.


1
Interessante! Gostaria de saber se é apenas uma otimização ausente ou a necessidade de analisar tantos arquivos, pois não há arquivos de interface.
Zaph 27/08/14

2
Tive problemas semelhantes e, no final, percebi que era por causa de operadores personalizados usados ​​nas classes de entidade para desserializar do JSON. Se você estiver usando algum, sugiro que tente converter a função normal uma a uma e veja se alguma coisa muda.
Antonio

4
A compilação tornou-se extremamente lenta no meu projeto desde o XCode 6 beta 6. Onde não tenho certeza se é devido a alterações na versão beta ou devido ao meu código. Mas meu projeto ainda não é grande (~ 40-50 arquivos Swift).
BadmintonCat

2
Compilar tornou-se insuportavelmente lento à medida que meu projeto cresceu. Também dependo de vários pods, o que com certeza exaspera o problema. Isso está usando a recente versão não beta.
Andy Andy

2
A construção incremental ainda é feita em uma "análise conservadora de dependência, portanto, você ainda poderá ver mais arquivos sendo reconstruídos do que o absolutamente necessário". Espero que melhore com o tempo.
nmdias

Respostas:


70

Bem, aconteceu que Rob Napier estava certo. Foi um único arquivo (na verdade, um método) que estava causando a falha do compilador.

Agora não me interpretem mal. O Swift recompila todos os seus arquivos a cada vez, mas o melhor agora é que a Apple adicionou feedback de compilação em tempo real sobre os arquivos que compila, então o Xcode 6 GM agora mostra quais arquivos Swift estão sendo compilados e o status da compilação em tempo real como você pode ver nesta captura de tela:

Digite a descrição da imagem aqui

Portanto, é muito útil saber quais arquivos estão demorando tanto. No meu caso, era este pedaço de código:

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

return dic.copy() as NSDictionary

porque a propriedade titleera do tipo var title:String?e não NSString. O compilador estava ficando louco ao adicioná-lo ao NSMutableDictionary.

Alterando para:

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

return dic.copy() as NSDictionary

fez a compilação passar de 10/15 segundos (talvez até mais) para um único segundo ... incrível.


3
Obrigado por acompanhar a resposta. Isso pode ser muito útil para outras pessoas que estão perseguindo lá embaixo, o mecanismo de inferência de tipo fica atolado durante a compilação.
Rob Napier

1
Onde você chegou a esse ponto de vista @apouche? Eu não vê-lo em xcode
Eric

2
Você precisa abrir o assistente de depuração (CMD + 8) e clicar na versão atual
apouche

1
Sim, eu tenho certeza que a Apple irá otimizar isso mais tarde, caso contrário, fazer projetos do mundo real rapidamente está condenado aqui e ali.
apouche 17/09/14

1
Como posso chegar a essa ferramenta que mostra quais arquivos estão sendo compilados?
Jgvb

41

Tentamos várias coisas para combater isso, pois temos cerca de 100 mil linhas de código Swift e 300 mil linhas de código ObjC.

Nosso primeiro passo foi otimizar todas as funções de acordo com a saída dos tempos de compilação da função (por exemplo, conforme descrito aqui https://thatthinginswift.com/debug-long-compile-times-swift/ )

Em seguida, escrevemos um script para mesclar todos os arquivos rápidos em um arquivo, isso quebra os níveis de acesso, mas aumentou o tempo de compilação de 5 a 6 minutos para 1 minuto.

Agora isso está extinto, porque perguntamos à Apple sobre isso e eles aconselharam que deveríamos fazer o seguinte:

  1. Ative a 'otimização do módulo inteiro' na configuração de compilação 'Swift Compiler - Code Generation'. Selecione'Fast, Whole Module Optimization'

insira a descrição da imagem aqui

  1. Em 'Swift Compiler - Sinalizadores Personalizados', para seu desenvolvimento, adicione '-Onone'

insira a descrição da imagem aqui insira a descrição da imagem aqui

Quando esses sinalizadores são definidos, o compilador compila todos os arquivos Swift em uma etapa. Descobrimos com nosso script de mesclagem que isso é muito mais rápido do que compilar arquivos individualmente. No entanto, sem a -Onone'substituição, ele também otimizará todo o módulo, que é mais lento. Quando definimos o'-Onone' sinalizador nos outros sinalizadores Swift, ele interrompe a otimização, mas não para de compilar todos os arquivos Swift em uma única etapa.

Para obter mais informações sobre a otimização de todo o módulo, consulte a publicação no blog da Apple aqui - https://swift.org/blog/whole-module-optimizations/

Descobrimos que essas configurações permitem que nosso código Swift seja compilado em 30 segundos :-) Não tenho evidências de como funcionaria em outros projetos, mas sugiro que tente se os tempos de compilação Swift ainda são um problema para você.

Observe para as compilações da App Store, você deve deixar o '-Onone'sinalizador de fora, pois a otimização é recomendada para compilações de produção.


4
Muito obrigado por este conselho! Simplesmente não entendo por que não há nada assim em fontes oficiais (pelo menos fácil de encontrar), por exemplo, o artigo que você menciona deve (deve!) Fazer a observação -Onone. Por enquanto, não podemos usar a otimização de todo o módulo, porque causa uma falha no compilador ... Mas o seu conselho dá quase 10 x de aumento à nossa velocidade de compilação. No MacBook Air (anual de 2013), ele estava construindo cerca de 8 minutos, agora diminui para cerca de 1 minuto e metade do tempo gasto alternando entre alvos (temos aplicativos, extensões e poucas estruturas internas) e compilando storyboards
Ilya Puchka

Também testei esse método e é o único método mencionado que inclui o -Onone e diminui significativamente o tempo de compilação.
Vlad

Trabalhe com o meu também. Usando a -Ononeajuda para reduzir os tempos de construção. Muito obrigado companheiro!
Nahung89 04/04

34

Provavelmente tem pouco a ver com o tamanho do seu projeto. Provavelmente é algum trecho de código específico, possivelmente apenas uma linha. Você pode testar isso tentando compilar um arquivo por vez, em vez de todo o projeto. Ou tente assistir os logs de compilação para ver qual arquivo está demorando tanto.

Como um exemplo dos tipos de código que podem causar problemas, essa essência de 38 linhas leva mais de um minuto para compilar no beta7. Tudo isso é causado por este bloco:

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

Simplifique isso com apenas uma ou duas linhas e ele compila quase instantaneamente. O problema é que isso está causando crescimento exponencial (possivelmente fatorial) no compilador. Obviamente, isso não é o ideal, e se você puder isolar essas situações, abra radares para ajudar a limpar esses problemas.


Não sei se você viu meu comentário sobre a CompileSwiftfase. Leva todos os arquivos rápidos, mesmo que apenas um tenha sido modificado. Portanto, se for um arquivo que está demorando algum tempo (o que duvido muito), o compilador nunca dirá qual é.
apouche 7/09/14

10
Você pode compilar arquivos individuais usando swiftcpara ver quanto tempo eles demoram.
Rob Napier

Peço desculpas por não lhe dar a recompensa, porque não acredito nisso a princípio. Eu também tentei compilar arquivos um por um, mas era complicado de fazer (tinha que fornecer estruturas adequadamente e deps cada vez), então desisti. Por favor, veja a minha resposta mais recente a este post para explicação completa
apouche

Eu não acho que seja baseado no tamanho do projeto. Meu projeto tem apenas 4 arquivos rápidos e de repente começou a compilar incrivelmente lento. Ontem estava iluminando rápido. Não consigo identificar o que fiz no meu projeto em particular, exceto adicionar ícone e iniciar imagens.
Travis M.

33

Se você estiver tentando identificar arquivos específicos que diminuem o tempo de compilação, tente compilá-lo na linha de comando via xctool, que fornecerá os tempos de compilação arquivo por arquivo.

O que deve ser observado é que, por padrão, ele cria 2 arquivos simultaneamente por cada núcleo de CPU e não fornece o tempo decorrido "líquido", mas o tempo absoluto de "usuário". Dessa forma, todos os intervalos entre os arquivos paralelos são parecidos.

Para superar isso, defina o -jobssinalizador como 1 , para que não paralelize as compilações de arquivos. Levará mais tempo, mas no final, você terá tempos de compilação "líquidos" para comparar arquivo por arquivo.

Este é um comando de exemplo que deve fazer o truque:

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

A saída da fase "Compile Swift files" seria algo como:

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

Nesta saída, você pode identificar rapidamente quais arquivos estão demorando mais que outros para serem compilados. Além disso, você pode determinar com alta precisão se suas refatorações (conversões explícitas, dicas de tipo, etc ...) estão diminuindo o tempo de compilação para arquivos específicos ou não.

NOTA: tecnicamente, você também pode fazê-lo, xcodebuildmas a saída é incrivelmente detalhada e difícil de consumir.


1
Apenas certifique-se de que a Otimização de módulo inteiro do seu projeto esteja definida como falsa, ou ela não separará os arquivos rápidos individuais.
sabes

1
Veja Swift CompilerOptimization LevelparaFast, Whole Module Optimization [-O -whole-module-optimization]
Matt

26

No meu caso, o Xcode 7 não fez nenhuma diferença. Eu tinha várias funções exigindo vários segundos para compilar.

Exemplo

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

Depois de desembrulhar os opcionais, o tempo de compilação caiu 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)

Veja mais exemplos neste post e neste post .

Analisador de tempo de compilação para Xcode

I desenvolveu um plug-in Xcode que pode vir a calhar para qualquer um que experimenta estas questões.

imagem

Parece haver melhorias chegando no Swift 3, então esperamos ver nosso código Swift compilar mais rapidamente.


Incrível, espero que eu possa lhe dar mais de um. você é verdadeiro e seu plugin também é ótimo. Eu usei isso e meu tempo de compilação está diminuindo, o que significa desenvolvimento super rápido, porque esse opcional às vezes é um pesadelo e causa lentidão no compilador.
Hardikdevios

Fantástico! Sua ferramenta me ajuda muito. Obrigado
Phil

Ótimo plugin - realmente útil! Graças
365SplendidSuns

@Robert Gummesson, temos alguma ferramenta para o Código Objective-C?
Ashok

19

Provavelmente não podemos consertar o compilador Swift, mas algo que podemos consertar é o nosso código!

Há uma opção escondida no compilador Swift que imprime os intervalos de tempo exatas que compilador leva para compilar cada função: -Xfrontend -debug-time-function-bodies. Ele nos permite encontrar gargalos em nosso código e melhorar significativamente o tempo de compilação.

Simples, execute o seguinte no terminal e analise os resultados:

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

Awesome Brian Irace escreveu um artigo brilhante sobre o perfil de seus tempos de compilação Swift .


2
Para quem tem o zsh alias grep='noglob grep'primeiro, o grep othewise não funciona #
Jaime Agudo

16

A solução está lançando.

Eu tinha uma enorme variedade de toneladas de dicionários, assim:

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

Demorou aproximadamente 40 minutos para compilá-lo. Até que eu lancei os dicionários assim:

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

Isso funcionou para quase todos os outros problemas que encontrei em relação aos tipos de dados codificados no meu aplicativo.


6
Bem, sim, faz parte das otimizações que você faz para melhorar os tempos de compilação, mas ainda o principal problema com o compilador rápido atual, é que ele ainda recompila tudo o único arquivo rápido toda vez que você faz a menor modificação.
apouche 02/02

4
Seria engraçado se não fosse tão triste.
Tom Andersen

15

Uma coisa a observar é que o mecanismo de inferência do tipo Swift pode ser muito lento com os tipos aninhados. Você pode ter uma idéia geral do que está causando a lentidão, observando o log de compilação de unidades de compilação individuais que estão demorando muito tempo e depois copiando e colando o comando completo gerado por Xcode em uma janela do Terminal e pressionando CTRL- \ para obter alguns diagnósticos. Veja http://blog.impathic.com/post/99647568844/debugging-slow-swift-compile-times para obter um exemplo completo.


Essa é para mim a melhor resposta (veja o link). Eu poderia facilmente encontrar as duas linhas diferentes que eram um problema e resolvi decompondo minhas linhas em linhas menores.
Nico

Essa é uma resposta muito útil, porque mostra como descobrir onde o compilador ficou louco. No meu caso, foi o seguinte: 'curScore [curPlayer% 2] + curScore [2 + curPlayer% 2] == 3 && maker% 2 == curPlayer% 2' Assim que o mudei de 'if' para 'deixe ', resultou em "a expressão era complexa demais para ser resolvida em tempo razoável; considere dividir a expressão em subexpressões distintas"
Dmitry

Essa é definitivamente a maneira mais útil de resolver esse problema.
Richard Venable

9

Certifique-se também de que, ao compilar para depuração (Swift ou Objective-C), você defina como Build Active Architecture Only:

insira a descrição da imagem aqui


6

Como todo esse material está na versão beta e como o compilador Swift (pelo menos a partir de hoje) não está aberto, acho que não há resposta real para sua pergunta.

Antes de tudo, comparar o compilador Objective-C ao Swift é de alguma forma cruel. O Swift ainda está na versão Beta, e tenho certeza que a Apple está trabalhando no fornecimento de funcionalidades e na correção de bugs, mais do que na velocidade da luz (você não começa a construir uma casa comprando os móveis). Eu acho que a Apple otimizará o compilador no devido tempo.

Se, por algum motivo, todos os arquivos de origem tiverem que ser compilados completamente, uma opção pode ser criar módulos / bibliotecas separados. Mas essa opção ainda não é possível, pois o Swift não pode permitir bibliotecas até que o idioma esteja estável.

Meu palpite é que eles otimizarão o compilador. Pelo mesmo motivo que não podemos criar módulos pré-compilados, pode ser que o compilador precise compilar tudo do zero. Mas assim que o idioma atingir uma versão estável e o formato dos binários não estiver mais mudando, poderemos criar nossas bibliotecas e talvez (?) O compilador também consiga otimizar seu trabalho.

Mas acho que apenas a Apple sabe ...


"Pela mesma razão que não podemos criar módulos pré-compilados, pode ser que o compilador precise compilar tudo do zero." boa observação, não pensei nisso dessa maneira antes.
chakrit

1
2017 e ainda lento
Pedro Paulo Amorim

2017, com Xcode 9 e novo sistema de compilação e ainda lento
pableiros

2018 com o Xcode 9, eu tenho um projeto com mais de 50 arquivos rápidos, se eu fizer uma compilação limpa, agora passou 5 minutos e minha compilação ainda não foi concluída.
Chen Li Yong

5

Para o Xcode 8, vá para as configurações do projeto, em Editor> Adicionar configuração de compilação> Adicionar configuração definida pelo usuário e adicione o seguinte:

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

A adição desse sinalizador reduziu o tempo de compilação de compilação limpa de 7 minutos para 65 segundos para um projeto rápido de 40KLOC, milagrosamente. Também pode confirmar 2 amigos viram melhorias semelhantes em projetos empresariais.

Só posso assumir que isso é algum tipo de bug no Xcode 8.0

Edição: Parece que não funciona mais no Xcode 8.3 para algumas pessoas.


2
Onde estão as "configurações do projeto", por favor?
Raniys 26/10/16

@Raniys Clique no ícone azul no nível da raiz no painel esquerdo do Xcode.
Chris

Eu estou achando que a partir de Xcode 8.3 (não-beta) Isto já não funciona no meu caso :(
Chris

4

Infelizmente, o compilador Swift ainda não está otimizado para compilação rápida e incremental (a partir do Xcode 6.3 beta). Enquanto isso, você pode usar algumas das seguintes técnicas para melhorar o tempo de compilação do Swift:

  • Divida o aplicativo em Frameworks para reduzir o impacto da recompilação. Mas lembre-se de que você deve evitar dependências cíclicas no seu aplicativo. Para mais informações sobre este tópico, verifique este post: http://bits.citrusbyte.com/improving-swift-compile-time/

  • Use Swift para partes do seu projeto que são bastante estáveis ​​e não mudam frequentemente. Para outras áreas em que você precisa alterar com muita frequência ou áreas que exigem muitas iterações de compilação / execução (quase todas as coisas relacionadas à interface do usuário), use melhor o Objective-C com uma abordagem de combinação e combinação.

  • Experimente a injeção de código de tempo de execução com 'Injection for Xcode'

  • Use o método roopc: http://roopc.net/posts/2014/speeding-up-swift-builds/

  • Alivie o mecanismo de inferência do tipo rápido, dando algumas dicas com elencos explícitos.


4

A construção rápida de matrizes e dicionários parece ser uma causa bastante popular para isso (especialmente para você que tem experiência em Ruby ), ou seja,

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

provavelmente será a causa em que isso deve corrigi-lo:

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

4

Para depuração e teste, use as seguintes configurações para reduzir o tempo de compilação de cerca de 20 minutos para menos de 2 minutos,

  1. Nas configurações de criação do projeto, procure por "Otimização". Gire a depuração para "Mais rápido [-O3]" ou acima.
  2. Definir construção para arquitetura ativa: SIM
  3. Formato de informações de depuração: DWARF
  4. Otimização do módulo inteiro: NÃO

Eu perdi inúmeras horas esperando a construção do projeto, apenas para perceber que tinha que fazer uma pequena alteração e tive que esperar mais 30 minutos para testá-lo. Essas são as configurações que funcionaram para mim. (Ainda estou experimentando as configurações)

Porém, certifique-se de definir pelo menos "DWARF com dSYM" (se você deseja monitorar seu aplicativo) e Construir Arquitetura Ativa como "NÃO" para liberação / arquivamento para enviar para o iTunes Connect (lembro-me de desperdiçar algumas horas aqui também).


4
Posso estar errado, mas não definir níveis de otimização aumentados realmente aumentaria o tempo de compilação? Os níveis de otimização melhorarão o desempenho do tempo de execução.
Michael Waterfall

1
Set Build for Active Architecture: YESme deu uma redução de aproximadamente 45% no tempo de compilação. Muito obrigado.
Jean Le Moignan 18/10/2015

4

O compilador gasta muito tempo deduzindo e verificando os tipos. Portanto, adicionar anotações de tipo ajuda muito o compilador.

Se você tiver muitas chamadas de funções em cadeia, como

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

Em seguida, o compilador leva um tempo para descobrir qual sumdeve ser o tipo . Adicionar o tipo ajuda. O que também ajuda é puxar as etapas intermitentes para variáveis ​​separadas.

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

Especialmente para tipos numéricos CGFloat, Intpode ajudar bastante. Um número literal como 2pode representar muitos tipos numéricos diferentes. Portanto, o compilador precisa descobrir, a partir do contexto, qual é.

As funções que levam muito tempo para serem visualizadas +também devem ser evitadas. O uso de vários +para concatenar várias matrizes é lento porque o compilador precisa descobrir qual implementação de +deve ser chamada para cada uma +. Portanto, use a var a: [Foo]com append()se possível.

Você pode adicionar um aviso para detectar quais funções demoram a compilar no Xcode .

Em Configurações de compilação, para sua pesquisa de destino, selecione Outros sinalizadores Swift e adicione

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

avisar sobre todas as funções que levam mais de 100 ms para serem compiladas.


4

Para os projetos que misturam Objective C e Swift código, podemos definir -enable-bridging-pchem Other Swift Flags. Com isso, o cabeçalho da ponte é analisado apenas uma vez e o resultado (um arquivo temporário de "cabeçalho pré-compilado" ou "PCH") é armazenado em cache e reutilizado em todos os arquivos Swift no destino. A Apple afirmou que diminui o tempo de construção em 30%. Link de referência:

NOTA: Isso funciona apenas para o Swift 3.1 e superior.


2

A reinicialização do meu Mac fez maravilhas para esse problema. Passei de compilações de 15 minutos para compilações de 30 segundos apenas reiniciando.


1

O tempo de compilação rápido foi aprimorado no novo Xcode 6.3

Melhorias no compilador

O compilador Swift 1.2 foi projetado para ser mais estável e melhorar o desempenho em todos os aspectos. Essas alterações também fornecem uma experiência melhor ao trabalhar com o Swift no Xcode. Algumas das melhorias mais visíveis incluem:

Construções incrementais

Os arquivos de origem que não foram alterados não serão mais recompilados por padrão, o que melhorará significativamente os tempos de compilação nos casos mais comuns. Alterações estruturais maiores no seu código ainda podem exigir a reconstrução de vários arquivos.

Executáveis ​​mais rápidos

As compilações de depuração produzem binários que são executados consideravelmente mais rapidamente e as novas otimizações oferecem um desempenho ainda melhor da versão.

Melhor diagnóstico do compilador

As mensagens de erro e aviso mais claras, juntamente com os novos Fix-its, facilitam a gravação do código Swift 1.2 adequado.

Melhorias na estabilidade

As falhas mais comuns do compilador foram corrigidas. Você também deve ver menos avisos do SourceKit no editor do Xcode.


0

Aqui está outro caso que pode causar lentidão maciça com inferência de tipo. Operadores de coalescência .

Alterando linhas como:

abs(some_optional_variable ?? 0)

para

abs((some_optional_variable ?? 0) as VARIABLE_TYPE)

ajudou a trazer o meu tempo de compilação dos anos 70 para 13s


0

Nada funcionou para mim no Xcode 6.3.1 - quando adicionei cerca de 100 arquivos Swift, que o Xcode travou aleatoriamente na compilação e / ou indexação. Eu tentei uma opção modular sem sucesso.

Instalar e usar o Xcode 6.4 Beta realmente funcionou para mim.


0

Isso tem funcionado como mágica para mim - Speed ​​Up Swift Compilation . Reduziu o tempo de compilação para 3 minutos a partir de 10 minutos.

Ele diz que você deve ligar o Whole Module Optimizationao adicionar -Ononeem Other Swift Flags.

Eu estou usando Swift 3em Xcode 8.3/Xcode 8.2 .


0

Misturar literal inteiro e literal float em uma expressão também causa um longo tempo de compilação.

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

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

Muitas expressões de 1000 + ms em tempo de compilação são reduzidas para 10 ~ 100ms depois de eu colocar um .0literal depois do número inteiro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.