-
Notifications
You must be signed in to change notification settings - Fork 821
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
Speed up SettingsBuilder #1221
Speed up SettingsBuilder #1221
Conversation
It's unnecessary to build up a whole grouped dictionary only to check if all platforms are identical and then immediately discard the dictionary. Instead we can check if all targets match the first platform, which avoids creating a new dictionary but also allows bailing early as soon as a non-matching platform is found. Generating a large project (36MB json spec) on an M1 Max machine leads to a ~6% total speedup: 28.48s vs 30.07s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks @jpsim. Could you please add a changelog entry as well under Next Version
.
Given your large amount of targets I imagine there are a wealth of small performance optimisations like this.
Changelog entry added |
The number one thing we could do to optimise project generation would be to parallelise the source generator. From the 10s mark to the 45s mark in this trace, the bottleneck is recursively walking the directory tree in SourceGenerator.getSourceChildren(...), which runs single-threaded. I've tried parallelising that work but it's challenging given that the XcodeProj structure that gets built up at that stage uses a lot of reference types that are unsafe to modify from multiple threads. I've tried introducing locks and serial queues to address that, but haven't gotten it to work so far. I also tried to use Swift Concurrency to help parallise this processing stage safely, but the CLI library XcodeGen uses doesn't support async commands, so I gave up on that as well. swift-argument-parser does though, if you wanted to go down that route. My next attempt would build up the directory tree in memory in a parallelised way and then use that tree for further work that is challenging to parallelise, but I'm not sure how much of a win we'll get from that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah been thinking a move to swift-argument-parser would be good in the long run
Thank you for this improvement @jpsim 👍 It has helped with an improvement of 25% for our project ❤️
@jpsim Would be amazing if you could try out a build from this MR and share your feedback 🙏 I've been using a build from this branch for the past 2 years, and it has been super useful to save time spent generating projects. On an average I am seeing a 50% improvement in project generation times compared to master. |
It's unnecessary to build up a whole grouped dictionary only to check if all platforms are identical and then immediately discard the dictionary.
Instead we can check if all targets match the first platform, which avoids creating a new dictionary but also allows bailing early as soon as a non-matching platform is found.
Generating a large project (36MB json spec) on an M1 Max machine leads to a ~6% total speedup: 28.48s vs 30.07s.