There is an open source library of astronomic algorithms called SwiftAA which is essentially a Swift wrapper for another well-known open source AA+ library written in C++. It uses C as an intermediate layer between Swift and C++ (it used to be Objective-C but they switched to pure C later).
I want to add a new feature to SwiftAA which haven't been ported from AA+ yet and I tempted to try new C++ interoperability feature, since it allows me to use C++ directly from Swift code without intermediary levels. I enabled C++ interoperability and I manage to get it working. However, I noticed that the compilation time jumped 3-4 times after I enable cxx-interop.
Compiling current version of SwiftAA with Xcode 15.4 takes about 32 seconds on my fairly old MacBook Pro 16" 2019 (Intel). But compiling the same thing with just the C++ interoperability enabled takes 113 seconds! I tried Xcode 16 beta 3 without much success (31 s without interop and 104 s with interop). Note: if you're going to try it on your machine, please delete DerivedData before every test.
So, why enabling C++ interoperability increases compilation time so drastically? Do you have any ideas how to improve it?
Does anybody knows if compilation time is expected to rise so dramatically with cxx-interop or it is something unique in this project which makes compilation so slow. What's your mileage?
Thanks for bringing up this document, I wasn't aware of its existence. Here is what I found so far.
I tried to turn on whole-module optimization and I found it doesn't improve things much (107s vs 113s).
I tried to profile compilation with Instruments (CPU Counters template) and I found the most active swift-frontend process spends most of the time in clang::ParseAST(clang::Sema&, bool, bool) function (see attached screenshot). The heaviest trace contained what looks like a 20-times deep recursion into clang::ASTReader::ReadASTCore(...) function (again, see screenshot).
Both -debug-time-function-bodies and -debug-time-expression-type-checking didn't show any particularly slow functions/expressions. There were only 2 functions around 500ms, all others were below 15ms.
-print-clang-stats doesn't looks suspicious to me (header only):
While testing all those scenarios I noticed peculiar behavior of Xcode compilation progress indicator (Building 123/456 files) along with CPU info in Activity Monitor. After starting the build process Xcode invokes a lot of swift-frontend processes which all consume a lot of CPU and the progress indicator moves quickly. Then the progress indicator stops moving and I see only one swift-frontend process actually using the CPU significantly. This continues for about a minute and then things get back to normal and compilation ends successfully.
The slowdown is likely happening because enabling C++ interop means the compiler can't use the precompiled Clang modules, since it is building those modules in a different language mode (Objective-C++ vs Objective-C) and some of the symbols are treated differently.
After the initial build, subsequent builds should be much faster, even when the project needs to be rebuilt entirely – I would expect the majority of the time to be spent on re-building system modules in Objective-C++ mode. Are incremental builds that enable C++ interop also substantially slower?
What is interesting that Xcode's Report Navigator attributes all the slowness to the target SwiftAA, which uses only Swift and not to AABridge, which uses C/C++.
I can confirm this. I have a project that uses a C library and for some reason I had C++ interoperability turned on. Compiling the .swift files took forever and I couldn't figure out why, until I realized it was the files interfacing with my C library. Since it was C there was no reason for the C++ interoperability, and once I had that disabled compile time was back to normal.