Tuesday, February 27, 2024

Slow Swift Macro Compilation

Vatsal Manot:

Folks, if you’re also frustrated with the state of Swift Macros (w.r.t. compile times), please engage on the forums thread here.

I can’t think of any other language where such a fundamental feature is dependent on a heavy source package that needs to be recompiled every clean build.

John Bushnell:

Prior to adding macros one xcframework takes 257.7 seconds (4.3 minutes) to build. After adding macros it takes 2004.5 seconds (33.4 minutes). This is a 7.76x increase. This is with one macro implemented in one location in code, so it’s not related to how many times the macro is used.

This speed decrease makes the macros support currently unusable for us.

[…]

There’s also a secondary issue, which because of the speed issue I don’t really need to take it further at this point, but it’s that tests do not support these macros for some reason when run from the command line.

Wade Tregaskis:

Same story as everyone else, in a nutshell - I saw some nice-looking package (swift-foundation-extensions, in this instance), added it to my project, and then saw my builds suddenly taking way longer. Then noticed the dreaded “SwiftSyntax” named in the build logs.

What was a clean build time of about fifteen seconds became several minutes.

(“how often do you do clean builds, though, really?” - ugh, a lot. I’m using Xcode and it’s got some bugs regarding detecting changed sources, not to mention its infamous bugginess regarding stale compiler errors)

John McCall:

The LSG is aware that there are build-system issues causing a lot of pain for macro adopters and their downstreams. From an abstract language perspective, I don’t think any of those problems are particularly challenging to the point of requiring an overall design change to macros; the project just needs to put in the work to fix them. I can’t tell you when that will happen, though, which I know is not a satisfying answer.

Vatsal Manot:

Be aware of the fact that you’re adding ~38,000 LoC of Swift source code to your project. This cost is forwarded to anyone consuming your Swift packages.

Be aware of the fact that SPM currently fetches the entire git history of the SwiftSyntax repo. This is a separate but, in my view, not unrelated issue as it directly factors into the cost of adopting macros.

Just adding SwiftSyntax can potentially add up to 12 minutes to your build time on Xcode Cloud as noted by @Ignacio_Soto.

It’s peculiar enough that a core language feature is tied to a still-maturing package manager riddled with performance/build-systems issues, but what I find extremely disappointing is that these issues aren’t mentioned anywhere in any official documentation/release notes.

Previously:

Update (2024-02-28): Martin Pilkington:

A clean build of my CoppiceCore framework & tests now takes 2m36s, only about 10s of which is my code

Apple really needs to switch to Macros linking against a pre-build version included in Swift distributions if they want Macros to be a feature many people use

Update (2024-03-01): alloca:

I feel like I’ve seen clean build times increase by maybe 30-60 seconds on my M1 Pro when adding macros. Am I missing something? How are people getting several minute increases?

Stephen Celis (via Helge Heß):

Introducing SwiftSyntax to a project immediately incurs an additional 20 second debug build cost to a project, which may not seem like much, but that’s an extra minute for every 3 cleans. Things get much slower when building for release with whole module optimization: over 4 minutes just for SwiftSyntax. This issue from January highlights the problem, but there isn’t a lot of discussion around how it might be addressed.

[…]

Beyond build times, SwiftSyntax is a complex project to depend on, and it’s unclear how to version a project that depends on it. I started this discussion a few days ago and was hoping for guidance there, but I’ll restate the problem here. Because SwiftSyntax is a moving target and versioned alongside Swift releases, how can a library adopt macros and be compatible with multiple Swift versions at the same time?

Update (2024-03-11): Vatsal Manot:

Friendly reminder that there’s still no ETA on when the massive compilation time issue for Swift Macros will be fixed.

I’d personally recommend holding off on adoption until there’s an official update from the team on this.

Saagar Jha:

As I watch complaints mount about swift-syntax compile times, I wonder if Apple remembers the time when them ignoring the concerns of impatient developers led to the infection of hundreds of millions of iOS devices in one of the most successful supply-chain backdoor attacks ever

Nobody’s going to do the whole Reflections on Trusting Trust thing but the longer it takes for your project to build the easier it gets for me to offer you my precompiled binaries instead. And interestingly enough these binaries happen to have direct control of code generation…

4 Comments RSS · Twitter · Mastodon

Wow, that sounds amateurish at best…

Those who fail to learn from C++, end up repeating its mistakes.

For me this bad culture of inefficient, fragmenting or wasteful "new" things everywhere at Apple is such a downer.

I really recommend to try this (because I have done it): Switch off SIPS on your Apple Silicon Mac, start a new project in Obj-C, use some bindings, compile and debug.
Less code, faster to compile, better to debug.

Why can't "the new" feel like this?
What if all this effort would have gone into that direction?

Instead we have now 4 different ways to create UI's.

+1

Objective-C is still the better language after essentially being frozen in time for ten years while Apple has been monkeying around on Swift. The compiler is still slow and crashes all the time.

Imagine how much better software quality would be if they would have made ObjC 3.0 instead of trying to burn it all down.

Ten years working on a car. Ten years of Swift. Might be time to show some more of that courage.

Leave a Comment