스위프트 컴파일 시간이 왜 이렇게 느린가요?


210

Xcode 6 Beta 6을 사용하고 있습니다.

이것은 지금 당장 나를 괴롭힌 적이 있지만 지금은 거의 사용할 수없는 시점에 도달하고 있습니다.

내 프로젝트는 적당한 크기의 65 Swift 파일과 몇 개의 브리지 된 Objective-C 파일 (실제로 문제의 원인이 아님) 을 갖기 시작했습니다 .

응용 프로그램에서 거의 사용되지 않는 클래스에 간단한 공백을 추가하는 것과 같이 Swift 파일을 약간 수정 한 것처럼 지정된 대상의 전체 Swift 파일이 다시 컴파일됩니다.

더 깊이 조사한 결과, 컴파일러 시간의 거의 100 %를 차지하는 것은 CompileSwiftXcode가 swiftc대상의 모든 Swift 파일 에서 명령을 실행하는 단계 라는 것을 알았습니다 .

추가 조사를 수행했으며 기본 컨트롤러로 앱 대리자를 유지하면 컴파일 속도가 매우 빨라지지만 점점 더 많은 프로젝트 파일을 추가할수록 컴파일 시간이 느려지기 시작했습니다.

이제 65 개의 소스 파일 만 있으면 매번 컴파일하는 데 약 8/10 초가 걸립니다. 전혀 빠르지 는 않습니다.

나는 제외하고는이 문제에 대해 이야기 사후 보지 못했지만 이 일을 하지만 그 경우에 하나의이야 만약 내가 궁금하네요 그래서 엑스 코드 (6)의 이전 버전을했다.

최신 정보

Alamofire , EulerCryptoSwift 와 같은 GitHub 에서 몇 가지 Swift 프로젝트를 확인 했지만 실제로 비교할 충분한 Swift 파일이 없었습니다. 내가 적당한 크기의 프로젝트를 시작한 것으로 밝혀진 유일한 프로젝트 는 SwiftHN 이며, 소스 파일이 수십 개인데도 여전히 동일한 것을 확인할 수 있었고, 간단한 공간 하나와 전체 프로젝트를 다시 컴파일해야했습니다. 작은 시간 (2/3 초).

분석기와 컴파일이 빠르게 진행되는 Objective-C 코드와 비교할 때, 이것은 스위프트가 큰 프로젝트를 처리 할 수 ​​없을 것 같지만, 내가 틀렸다고 말해주십시오.

Xcode 6 베타 7로 업데이트

여전히 개선이 없습니다. 이 말이 터지기 시작했습니다. #import스위프트 (Swift) 가 없기 때문에 애플이 어떻게 이것을 최적화 할 수 있을지 모르겠다.

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 베타 5 및 Swift 2.0으로 업데이트

어제 Apple은 베타 5를 출시했으며 릴리스 노트에서 다음과 같이 볼 수 있습니다.

Swift Language & Compiler • 증분 빌드 : 함수 본문 만 변경해도 더 이상 종속 파일이 다시 작성되지 않아야합니다. (15352929)

나는 그것을 시도했고 그것이 실제로 (정말!) 잘 작동한다고 말해야합니다. 그들은 증분 빌드를 신속하게 최적화했습니다.

swift2.0XCode 7 베타 5를 사용하여 브랜치 를 만들고 코드를 최신 상태로 유지 하는 것이 좋습니다 . 컴파일러의 향상된 기능에 만족할 것입니다 (그러나 XCode 7의 글로벌 상태는 여전히 느리고 버그가 있습니다)

Xcode 8.2로 업데이트

이 문제에 대한 마지막 업데이트 이후 오랜 시간이 지났습니다.

우리의 응용 프로그램은 이제 거의 독점적으로 Swift 코드의 약 20k 줄입니다. 스위프트 2와 스위프트 3 마이그레이션보다 빠릅니다. 2014 년 중반 Macbook Pro (2.5GHz Intel Core i7)에서 컴파일하는 데 약 5 / 6m가 소요되며 이는 깔끔한 빌드에서는 괜찮습니다.

그러나 애플이 다음과 같이 주장하지만 증분 빌드는 여전히 농담입니다.

Xcode는 작은 변경 사항이 발생한 경우 전체 대상을 다시 작성하지 않습니다. (28892475)

분명히 나는 ​​우리 중 많은 사람들 이이 넌센스를 확인한 후 웃었다 고 생각합니다 (프로젝트의 파일에 하나의 개인 (개인!) 속성을 추가하면 전체가 다시 컴파일됩니다 ...)

Apple 개발자 포럼 에서이 문제에 대해 더 많은 정보를 제공하는 스레드 를 지적하고 싶습니다 (이 문제에 대한 Apple 개발자의 커뮤니케이션에 감사드립니다)

기본적으로 사람들은 증분 빌드를 개선하기 위해 몇 가지를 생각해 냈습니다.

  1. HEADER_MAP_USES_VFS설정된 프로젝트 설정 추가true
  2. Find implicit dependencies당신의 계획에서 비활성화
  3. 새 프로젝트를 작성하고 파일 계층을 새 프로젝트로 이동하십시오.

솔루션 3을 시도하지만 솔루션 1/2은 우리에게 효과가 없었습니다.

이 전체 상황에서 아이러니하게도 재미있는 것은 우리가 Xcode 6을 사용하고있는이 문제에 대한 첫 번째 게시물을 살펴보면 첫 번째 컴파일 부진에 도달했을 때 swift 1 또는 swift 1.1 코드를 믿으며 약 2 년 후에 Apple의 실제 개선에도 불구하고 상황은 Xcode 6에서와 마찬가지로 나빴습니다.

사실은 정말 그것 때문에 포함 매일 좌절의 우리의 프로젝트의 Obj / C를 통해 스위프트을 선택 후회. (나는 심지어 AppCode로 전환하지만 다른 이야기입니다)

어쨌든 나는이 SO 게시물 이이 글을 쓰는 시점에서 32k + 조회수와 143 업을 가지고 있으므로 내가 유일한 사람이 아니라고 생각합니다. 이 상황에 비관적이지만 터널 끝 부분에 약간의 빛이있을 수 있습니다.

시간이 있고 용기가 있다면, 애플이 이것에 대해 레이더를 환영한다고 생각합니다.

다음 시간까지! 건배

Xcode 9로 업데이트

오늘 이것을 우연히 발견 하십시오 . Xcode는 현재 끔찍한 성능을 향상시키기 위해 새로운 빌드 시스템을 조용히 도입했습니다. 작업 공간 설정을 통해 활성화해야합니다.

여기에 이미지 설명을 입력하십시오

아직 시도했지만이 게시물이 완료되면 업데이트됩니다. 그래도 유망 해 보인다.


1
흥미 롭습니다! 인터페이스 파일이 없기 때문에 최적화가 누락되었거나 많은 파일을 구문 분석 해야하는지 궁금합니다.
zaph

2
비슷한 문제가 있었지만 결국 엔터티 클래스에서 JSON에서 deserialize하는 데 사용되는 사용자 지정 연산자 때문이라는 것을 깨달았습니다. 당신이 어떤 것을 사용하고 있다면, 나는 당신이 하나씩 정상적인 기능으로 변환하고 변화가 있는지보십시오.
Antonio

4
XCode 6 베타 6 이후로 프로젝트에서 컴파일이 엄청나게 느려졌습니다. 베타 변경이나 코드로 인한 것인지 확실하지 않습니다. 그러나 내 프로젝트는 아직 크지 않습니다 (~ 40-50 Swift 파일).
배드민턴 고양이

2
프로젝트가 커지면서 컴파일 속도가 느려졌습니다. 또한 여러 포드에 의존하므로 문제가 심화됩니다. 최신 베타 버전을 사용하고 있습니다.
Andy

2
증분 빌드는 여전히 "보존 적 종속성 분석에서 수행되므로 절대적으로 필요한 것보다 더 많은 파일을 다시 작성하는 것을 볼 수 있습니다." 바라건대, 시간이지나면서 향상 될 것입니다.
nmdias 2012

답변:


70

롭 네이피어가 옳다는 것이 밝혀졌습니다. 컴파일러가 berzek으로 이동하게하는 것은 하나의 단일 파일 (실제로 하나의 방법)이었습니다.

이제 내가 틀리지 마 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 초 (아마도 더 많음)에서 1 초까지 ... 놀랍습니다.


3
답장을 보내 주셔서 감사합니다. 이것은 컴파일하는 동안 형식 유추 엔진이 다운되는 사람들에게 매우 유용 할 수 있습니다.
Rob Napier

1
이 뷰 @apouche를 어디로 가셨습니까? xcode에서는 보이지 않습니다
Eric

2
디버그 지원 (CMD + 8)을 열고 현재 빌드를 클릭해야합니다
apouche

1
그래, 나중에 애플이 이것을 최적화 할 것이라고 확신한다. 그렇지 않으면 실제 프로젝트를 신속하게 수행하는 것이 여기저기서 끝날 것이다.
apouche

1
어떤 파일이 컴파일되고 있는지 보여주는이 도구를 어떻게 이용할 수 있습니까?
jgvb

42

우리는 약 100k 라인의 Swift 코드와 300k 라인의 ObjC 코드를 가지고 있기 때문에 이것을 극복하기 위해 몇 가지 노력을 기울였습니다.

첫 번째 단계는 함수 컴파일 시간 출력에 따라 모든 함수를 최적화하는 것입니다 (예 : https://thatthinginswift.com/debug-long-compile-times-swift/에 설명 된대로 )

다음으로 모든 신속한 파일을 하나의 파일로 병합하는 스크립트를 작성했습니다. 이로 인해 액세스 수준이 떨어지지 만 컴파일 시간이 5-6 분에서 ~ 1 분으로 단축되었습니다.

Apple에 문의하여 다음과 같은 조치를 취해야한다고 권고했기 때문에 이는 현재 소멸되었습니다.

  1. 'Swift Compiler-Code Generation'빌드 설정에서 '전체 모듈 최적화'를 켜십시오. 고르다'Fast, Whole Module Optimization'

여기에 이미지 설명을 입력하십시오

  1. 개발 빌드를 위해 'Swift Compiler-Custom Flags'에서 '-Onone'

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

이 플래그가 설정되면 컴파일러는 모든 Swift 파일을 한 단계로 컴파일합니다. 병합 스크립트를 사용하면 파일을 개별적으로 컴파일하는 것보다 훨씬 빠릅니다. 그러나 ' -Onone'재정의가 없으면 전체 모듈도 최적화되므로 속도가 느려집니다. '-Onone'다른 Swift 플래그에 플래그를 설정하면 최적화가 중지되지만 한 번에 모든 Swift 파일 컴파일이 중지되지는 않습니다.

전체 모듈 최적화에 대한 자세한 내용은 Apple 블로그 게시물 ( https://swift.org/blog/whole-module-optimizations/)을 참조하십시오.

이러한 설정을 통해 Swift 코드가 30 초 안에 컴파일 될 수 있다는 것을 알았습니다 .-) 다른 프로젝트에서 어떻게 작동하는지에 대한 증거는 없지만 Swift 컴파일 시간이 여전히 문제가되는 경우 시도해 보는 것이 좋습니다.

App Store 빌드의 경우 '-Onone'프로덕션 빌드에 최적화가 권장 되므로 플래그를 남겨 두어야 합니다.


4
이 조언에 감사드립니다! 나는 공식 소스 (적어도 찾기 쉬운)에 왜 그런 것이 없는지 이해하지 못합니다. 예를 들어 언급 한 기사에 대해 언급해야합니다 -Onone. 컴파일러 충돌을 일으키기 때문에 지금은 전체 모듈 최적화를 사용할 수 없습니다 ... 그러나 여러분의 조언은 빌드 속도를 거의 x10 향상시킵니다. 맥북 에어 (연간 2013)에 지금은이 목표를 전환하는데 소비하는 시간 (우리는 응용 프로그램, 확장 및 몇 자체 프레임 워크를) 및 컴파일 스토리 보드의 약 1 분 반까지의, 약 8 분 구축되었다
일리아 Puchka을

또한이 방법을 테스트했으며 -Onone을 포함하는 언급 된 방법이며 빌드 시간이 크게 단축됩니다.
Vlad

나와 함께 일하십시오. -Onone도움말을 사용하여 빌드 시간 단축 많은 친구 감사합니다!
nahung89

34

프로젝트 크기와 거의 관련이 없습니다. 아마도 특정 코드 조각 일 수도 있고 아마도 한 줄일 수도 있습니다. 전체 프로젝트가 아닌 한 번에 하나의 파일을 컴파일하여이를 테스트 할 수 있습니다. 또는 빌드 로그를보고 어떤 파일이 오래 걸리는지 확인하십시오.

문제를 일으킬 수있는 코드 종류의 예로, 이 38 줄 짜리 요점 은 베타 7에서 컴파일하는 데 1 분 이상 걸립니다. 이 모든 것은이 하나의 블록으로 인해 발생합니다 :

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

한두 줄만으로 단순화하면 거의 즉시 컴파일됩니다. 문제는 컴파일러에서 지수 성장 (아마도 계승 성장)을 일으키는 것입니다. 분명히 이상적이지는 않으며 그러한 상황을 격리 할 수 ​​있다면 레이더를 열어서 문제를 해결하는 데 도움이됩니다.


나는 당신이 그 CompileSwift단계 에 관한 나의 의견을 보지 못했다 하나만 수정하더라도 모든 신속한 파일이 필요합니다. 따라서 시간이 걸리는 파일 (확실히 의심되는 파일) 인 경우 컴파일러는 파일이 무엇인지 알려주지 않습니다.
apouche

10
swiftc시간이 얼마나 걸리는지 사용하여 개별 파일을 컴파일 할 수 있습니다.
Rob Napier

나는 처음에 그것을 믿지 않기 때문에 당신에게 현상금을주지 않은 것에 대해 사과드립니다. 또한 파일을 하나씩 컴파일하려고 시도했지만 번거롭게해야했습니다 (올바로 프레임 워크를 제공하고 매번 뎁스해야했습니다). 전체 설명을 보려면이 게시물에 대한 최신 답변을 참조하십시오
apouche

나는 그것이 프로젝트 크기를 기반으로한다고 생각하지 않습니다. 내 프로젝트에는 4 개의 빠른 파일 만 있으며 갑자기 컴파일이 너무 느리게 시작되었습니다. 어제 빠른 조명이었습니다. 아이콘 추가 및 이미지 실행을 제외하고 특히 프로젝트에서 수행 한 작업에 손가락을 넣을 수 없습니다.
Travis M.

33

컴파일 시간을 늦추는 특정 파일을 식별하려는 경우 xctool 을 통해 명령 줄에서 파일을 컴파일하면 파일별로 컴파일 시간을 줄 수 있습니다.

주목할 것은 기본적으로 각 CPU 코어 당 2 개의 파일을 동시에 빌드하며 "net"경과 시간이 아니라 절대 "user"시간을 제공한다는 것입니다. 이렇게하면 병렬화 된 파일 사이의 모든 타이밍이 매우 유사 해 보이고 매우 유사 해 보입니다.

이를 극복하려면 파일 빌드를 병렬화하지 않도록 플래그를 1로 설정하십시오-jobs . 시간이 더 걸리지 만 결국에는 파일별로 파일을 비교할 수있는 "net"컴파일 시간이 있습니다.

다음은 트릭을 수행해야하는 명령 예입니다.

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

"Swift 파일 컴파일"단계의 결과는 다음과 같습니다.

...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 용 빌드 시간 분석기

나는 엑스 코드 플러그에서 개발 된 이러한 문제가 발생하는 누군가를 위해 유용하게 사용할 수 있습니다.

영상

Swift 3에는 개선이있을 것으로 보이므로 Swift 코드가 더 빨리 컴파일되는 것을 보게 될 것입니다.


굉장합니다. +1 이상을 줄 수 있습니다. 당신은 진실하고 플러그인도 훌륭합니다. 나는 그것을 사용했으며 빌드 시간이 단축되었습니다.이 옵션은 때로는 악몽이기 때문에 컴파일러가 느려지기 때문에 초고속 개발을 의미합니다.
hardikdevios

환상적인! 당신의 도구는 많은 도움이됩니다. 감사합니다
Phil

훌륭한 플러그인-정말 유용합니다! 감사합니다
365SplendidSuns

@Robert Gummesson, Objective-C Code 도구가 있습니까?
Ashok

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

멋진 Brian Irace는 Swift 컴파일 시간 프로파일 링 에 대한 훌륭한 기사를 썼습니다 .


2
zsh를 alias grep='noglob grep'처음 사용 하는 사람들에게는 othewise grep이 작동하지 않습니다.
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
너무 슬퍼하지 않으면 재미있을 것입니다.
Tom Andersen

15

한 가지 주목할 점은 중첩 유형의 경우 스위프트 유형 유추 엔진이 매우 느릴 수 있다는 것입니다. 시간이 오래 걸리는 개별 컴파일 단위의 빌드 로그를보고 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' 'if'에서 'let'으로 이동하자마자 ', 합리적인 표현으로 표현하기에는 표현이 너무 복잡했습니다. 표현을 별개의 하위 표현으로 나누는 것을 고려하십시오 "
Dmitry

이 문제를 해결하는 데 가장 유용한 방법입니다.
Richard Venable 2016 년

9

또한 디버그 (Swift 또는 Objective-C)를 컴파일 할 때 활성 아키텍처 만 빌드로 설정했는지 확인하십시오.

여기에 이미지 설명을 입력하십시오


6

이 모든 것들이 베타 버전이고 Swift 컴파일러가 (적어도 오늘 현재) 열리지 않았기 때문에 귀하의 질문에 대한 실제 답변이없는 것 같습니다.

우선 Objective-C와 Swift 컴파일러를 비교하는 것은 다소 잔인합니다. Swift는 여전히 베타 버전이며 Apple은 기능을 제공하고 버그를 수정하는 것보다 번개 속도를 제공하는 것 이상입니다 (가구를 구입하여 집을 짓기 시작하지는 않습니다). 애플이 적시에 컴파일러를 최적화 할 것으로 생각합니다.

어떤 이유로 모든 소스 파일을 완전히 컴파일해야하는 경우 별도의 모듈 / 라이브러리를 작성하는 옵션이있을 수 있습니다. 그러나 언어가 안정 될 때까지 Swift에서 라이브러리를 허용 할 수 없으므로이 옵션은 아직 가능하지 않습니다.

내 생각에 그들은 컴파일러를 최적화 할 것입니다. 사전 컴파일 된 모듈을 만들 수없는 것과 같은 이유로 컴파일러가 모든 것을 처음부터 컴파일해야 할 수도 있습니다. 그러나 언어가 안정적인 버전에 도달하고 바이너리 형식이 더 이상 변경되지 않으면 라이브러리를 만들 수 있으며 컴파일러는 (?) 작업을 최적화 할 수도 있습니다.

그래도 애플 만이 알고있는 것만으로도 ...


"사전 컴파일 된 모듈을 만들 수없는 것과 같은 이유로, 컴파일러는 모든 것을 처음부터 컴파일해야 할 수도 있습니다." 좋은 관찰, 전에는 그런 식으로 생각하지 않았습니다.
chakrit

1
2017 년과 여전히 느리다
Pedro Paulo Amorim

2017 엑스 코드 (9)과 새로운 시스템을 구축 여전히 느린와
pableiros

2018 년 Xcode 9에서 50 개 이상의 신속한 파일이있는 프로젝트가 있습니다. 깨끗한 빌드를하면 5 분이 지났으며 컴파일이 아직 완료되지 않았습니다.
Chen Li Yong

5

Xcode 8의 경우 프로젝트 설정으로 이동 한 다음 편집기> 빌드 설정 추가> 사용자 정의 설정 추가로 이동하여 다음을 추가하십시오.

SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

이 플래그를 추가하면 40KLOC 신속한 프로젝트를 위해 클린 빌드 컴파일 시간이 7 분에서 65 초로 줄었습니다. 또한 2 명의 친구가 엔터프라이즈 프로젝트에서 비슷한 개선을 보았 음을 확인할 수 있습니다.

나는 이것이 Xcode 8.0의 일종의 버그라고 가정 할 수 있습니다.

편집 : 일부 사람들에게는 Xcode 8.3에서 더 이상 작동하지 않는 것 같습니다.


2
"프로젝트 설정"은 어디에 있습니까?
Raniys

@Raniys Xcode의 왼쪽 창에서 루트 레벨에있는 파란색 아이콘을 클릭하십시오.
Chris

Xcode 8.3 (베타 이외)에서 더 이상 제 경우에는 작동하지 않습니다. (
Chris

4

불행히도 Swift 컴파일러는 (Xcode 6.3 베타 현재) 빠르고 증분 컴파일에 최적화되어 있지 않습니다. 한편 다음 기술 중 일부를 사용하여 Swift 컴파일 시간을 향상시킬 수 있습니다.

  • 재 컴파일 영향을 줄이기 위해 앱을 프레임 워크로 분할하십시오. 그러나 앱에서 주기적 종속성을 피해야합니다. 이 주제에 대한 추가 정보는 다음 게시물을 확인하십시오. http://bits.citrusbyte.com/improving-swift-compile-time/

  • 매우 안정적이며 자주 변경되지 않는 프로젝트 부분에는 Swift를 사용하십시오. 매우 자주 변경해야하는 영역이나 많은 컴파일 / 실행 반복이 완료되어야하는 영역 (거의 모든 UI 관련 항목)의 경우 Objective-C를 믹스 앤 매치 방식으로 더 잘 사용하십시오.

  • 'Injection for Xcode'로 런타임 코드 삽입을 시도하십시오.

  • roopc 방법 사용 : http://roopc.net/posts/2014/speeding-up-swift-builds/

  • 명시 적 캐스트와 함께 힌트를 제공하여 신속한 형식 유추 엔진을 완화합니다.


4

스위프트 배열과 사전 구성은 (특히 루비 배경 에서 온 당신에게) 매우 인기있는 원인으로 보입니다 .

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. 전체 모듈 최적화 : NO

프로젝트를 빌드하기 위해 수많은 시간을 허비하면서 한 번만 변경하면되고 테스트를 위해 30 분 더 기다려야한다는 것을 깨달았습니다. 이것들은 나를 위해 일한 설정입니다. (나는 여전히 설정을 실험하고 있습니다)

그러나 릴리스 / 아카이빙이 iTunes Connect로 푸시되도록하려면 최소한 "dWAY with dSYM"(응용 프로그램을 모니터링하려는 경우) 및 빌드 활성 아키텍처를 "아니오"로 설정해야합니다 (여기서도 몇 시간을 낭비한 것을 기억하십시오).


4
틀릴 수도 있지만 최적화 수준을 높이 지 않으면 실제로 빌드 시간이 증가하지 않습니까? 최적화 수준은 런타임 성능을 향상시킵니다.
마이클 폭포

1
Set Build for Active Architecture: YES컴파일 시간이 약 45 % 단축되었습니다. 큰 감사를 드린다.
Jean Le Moignan

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 는 다양한 숫자 유형을 나타낼 수 있습니다. 따라서 컴파일러는 어떤 컨텍스트인지 파악해야합니다.

조회하는 데 많은 시간이 걸리는 기능 +도 피해야합니다. +컴파일러는 각 배열 +에 대해 어떤 구현을 호출해야하는지 파악해야하므로 여러 배열을 사용하여 여러 배열을 연결하는 것이 느립니다 +. 따라서 가능한 경우 var a: [Foo]with를 append()대신 사용하십시오.

Xcode에서 컴파일이 느린 함수 를 감지하는 경고를 추가 할 수 있습니다 .

에서 빌드 설정 을위한 대상 검색을위한 다른 스위프트 플래그 및 추가

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

컴파일하는 데 100ms 이상 걸리는 모든 함수에 대해 경고합니다.


4

오브젝티브 C와 스위프트 코드를 믹스 프로젝트의 경우, 우리는 설정할 수 있습니다 -enable-bridging-pch에서 Other Swift Flags. 이를 통해 브리징 헤더가 한 번만 구문 분석되고 결과 (임시“사전 컴파일 된 헤더”또는“PCH”파일)가 캐시되고 대상의 모든 Swift 파일에서 재사용됩니다. 애플은 제작 시간을 30 % 단축한다고 주장했다. 참조 링크 :

참고 : 이것은 Swift 3.1 이상에서만 작동합니다.


2

Mac을 재부팅하면이 문제가 궁금해졌습니다. 재부팅으로 15 분 빌드에서 30 초 빌드로 갔다.


1

새로운 Xcode 6.3에서 신속한 컴파일 시간 개선

컴파일러 개선

Swift 1.2 컴파일러는보다 안정적이고 모든면에서 성능을 향상 시키도록 설계되었습니다. 이러한 변경 사항은 Xcode에서 Swift로 작업 할 때 더 나은 환경을 제공합니다. 가장 눈에 띄는 개선 사항은 다음과 같습니다.

증분 빌드

변경되지 않은 소스 파일은 더 이상 기본적으로 다시 컴파일되지 않으므로 대부분의 경우 빌드 시간이 크게 향상됩니다. 코드를 크게 구조적으로 변경하면 여러 파일을 다시 작성해야 할 수도 있습니다.

빠른 실행 파일

디버그 빌드는 상당히 빠르게 실행되는 바이너리를 생성하며 새로운 최적화는 더 나은 릴리스 빌드 성능을 제공합니다.

더 나은 컴파일러 진단

새로운 Fix-its와 함께보다 명확한 오류 및 경고 메시지를 통해 올바른 Swift 1.2 코드를보다 쉽게 ​​작성할 수 있습니다.

안정성 개선

가장 일반적인 컴파일러 충돌이 수정되었습니다. Xcode 편집기에서 SourceKit 경고가 줄어 듭니다.


0

다음은 유형 유추로 막대한 속도 저하를 유발할 수있는 또 다른 사례입니다. 통합 연산자 .

다음과 같은 줄 바꾸기 :

abs(some_optional_variable ?? 0)

abs((some_optional_variable ?? 0) as VARIABLE_TYPE)

컴파일 시간을 70에서 13으로 가져 왔습니다.


0

Xcode 6.3.1에서는 아무것도 효과가 없었습니다 .Arround 100 Swift 파일을 추가했을 때 Xcode가 빌드 및 / 또는 인덱싱에서 임의로 중단되었습니다. 나는 성공하지 못한 모듈 옵션을 시도했다.

Xcode 6.4 Beta를 설치하고 사용하는 것이 실제로 효과적이었습니다.


0

이것은 나를 위해 마술처럼 작동했습니다- 빠른 컴파일 속도 . 컴파일 시간이 10 분에서 3 분으로 줄었습니다.

그것은 당신이 켜해야한다고 말했습니다 Whole Module Optimization추가하는 동안 -OnoneOther Swift Flags.

Swift 3Xcode 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

.0정수형 리터럴을 넣은 후 많은 1000 + ms 컴파일 타임식이 10 ~ 100ms로 줄어 듭니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.