Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2461] Long compilation times with bridging header and 100s of .swift files #45066

swift-ci opened this issue Aug 23, 2016 · 6 comments
compiler The Swift compiler in itself improvement


Copy link

Previous ID SR-2461
Radar rdar://problem/20715602
Original Reporter diegosanchezr (JIRA User)
Type Improvement
Status Reopened

Attachment: Download

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Improvement
Assignee graydon (JIRA)
Priority Medium

md5: b167791eaac0c50f1c8bcc3148c19f92

Issue Description:

Environment: Xcode 7.3.1. Swift 2.2 (can't migrate project to Swift 3 yet)
We're suffering very long compilation times in our project.
Each swift file takes more than 1 second to compile
If I have a file with 3 classes takes 1/3 of the time if I do 1 file per class

Two random files
-Xfrontend -debug-time-function-bodies
pbpaste | grep [1-9].[0-9]ms | sort -nr

File 1:
14.7ms  XXX.swift:33:21 final get {}
14.0ms  XXX.swift:28:22 final get {}
13.7ms  XXX.swift:28:58 (closure)
12.5ms  XXX.swift:270:22    get {}
12.2ms  XXX.swift:270:66    (closure)
9.0ms   XXX.swift:53:22 final get {}
8.5ms   XXX.swift:53:58 (closure)
6.4ms   XXX.swift:186:21    @objc get {}
6.1ms   XXX.swift:186:95    (closure)
5.8ms   XXX.swift:8:22  get {}
5.6ms   XXX.swift:8:50  (closure)
5.5ms   XXX.swift:84:14 @objc final get {}
5.1ms   XXX.swift:142:22    get {}
5.1ms   XXX.swift:84:48 (closure)
4.5ms   XXX.swift:142:62    (closure)
3.6ms   <invalid loc>   get {}
3.0ms   XXX.swift:35:22 get {}
2.6ms   XXX.swift:35:119    (closure)
2.3ms   XXX.swift:272:14    get {}
2.1ms   XXX.swift:272:62    (closure)
2.1ms   XXX.swift:10:14 @objc get {}
1.8ms   <invalid loc>   get {}
1.8ms   XXX.swift:274:51    (closure)
1.4ms   XXX.swift:11:22 final get {}
1.3ms   XXX.swift:11:55 (closure)
1.2ms   XXX.swift:47:22 get {}
1.0ms   <invalid loc>   get {}

File 2:
22.1ms  XXX.swift:28:22 final get {}
21.6ms  XXX.swift:28:58 (closure)
18.6ms  XXX.swift:32:84 get {}
16.0ms  XXX.swift:33:21 final get {}
12.6ms  XXX.swift:270:22    get {}
12.2ms  XXX.swift:270:66    (closure)
9.6ms   XXX.swift:56:17 public func selectMediaItems(items: [XXX])
8.8ms   XXX.swift:53:22 final get {}
8.3ms   XXX.swift:53:58 (closure)
6.4ms   XXX.swift:61:17 public func deselectMediaItems(itemsToDeselect: [YYY])
6.2ms   XXX.swift:186:21    @objc get {}
5.9ms   XXX.swift:186:95    (closure)
5.8ms   XXX.swift:8:22  get {}
5.6ms   XXX.swift:8:50  (closure)
5.4ms   XXX.swift:142:22    get {}
4.9ms   XXX.swift:142:62    (closure)
4.3ms   XXX.swift:69:17 public func toogleSelection(forItem item: ZZZZ)
3.8ms   XXX.swift:84:14 @objc final get {}
3.6ms   XXX.swift:84:48 (closure)
2.9ms   XXX.swift:35:22 get {}
2.5ms   XXX.swift:35:119    (closure)
2.3ms   XXX.swift:10:14 @objc get {}
2.1ms   <invalid loc>   get {}
1.9ms   XXX.swift:272:14    get {}
1.6ms   XXX.swift:272:62    (closure)
1.4ms   XXX.swift:274:51    (closure)
1.4ms   XXX.swift:11:22 final get {}
1.3ms   <invalid loc>   get {}
1.3ms   <invalid loc>   get {}
1.2ms   XXX.swift:47:22 get {}
1.2ms   XXX.swift:11:55 (closure)
1.1ms   <invalid loc>   get {}
1.1ms   <invalid loc>   get {}

Stack trace shows 2 slow paths: bridging header and type checking.

Looks to me that importing the bridging header could be done once per module instead of file, saving some time. Not sure also if much of the work of the type checking can be calculated up-front (maybe some kind of whole-module with -Onone so debug works?). Maybe there are some improvements already for Swift 3, but this project is quite big and we won't migrate until the final version.

Copy link

I'm afraid without a project there isn't much we can investigate here. However, we have fixed the issue with some variables being type-checked once per file instead of just when needed. Further improvements to Swift 2.3 are unlikely.

Copy link
Collaborator Author

Comment by Diego (JIRA)

Thanks @belkadan, we'll hope for improvements in Swift 3 then. What about ClangImporter::importBridgingHeader? it takes about 32% of the time in our project

Copy link

Again, hard to know what's going on without actually seeing your bridging header and the things it imports. Are you sure you're not just including the one-time cost of precompiling imported modules?

Copy link
Collaborator Author

Comment by Diego (JIRA)

Nah, I can literally see how files compile slowly in Xcode... I will try to synthesise a project that shows this issue!

Copy link
Collaborator Author

Comment by Diego (JIRA)

@belkadan I've attached some projects. 351 swift files and 701 obj-c files with empty methods. It's not as slow as ours but the same heavy stack traces appear in the profiler.

Swift 3 compiler is slightly faster than Swift 2, but it doesn't look like it will improve our compilation time dramatically.
Swif-3-one-file has all the code in a single file, which improves compilation time dramatically. The whole app compiles in 30 s in my machine (3x faster).

In our project, we suffer from these compilations from scratch when pulling code from upstream and, more often than we wanted, also randomly, but this would be a separate issue.

Hopefully there's room and resources for improvements in this area

Copy link

Thanks, Diego! It's at least a setup that's investigatable.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
compiler The Swift compiler in itself improvement
None yet

No branches or pull requests

2 participants