A roadmap for improving Swift performance predictability: ARC improvements and ownership control

Overall, I'm thrilled to see such a detailed roadmap for performance-critical Swift! It's going to be a significant positive leap for the language.

On the topic of memory model and performance predictability, one thing that I wish could be added to this discussion is immortal data, such as data stored in static data segments. Currently, the only way to achieve this in Swift—aside from some specific types like StaticString that explicitly produce it—is to do an optimized build, but the ObjectOutliner SILOptimizer pass is entirely unpredictable to the average Swift developer.

I'm also very interested in hearing more about lexical lifetimes, because I agree with @Karl here; in the values sorting example, it seems like the compiler could detect that the local argument values is no longer used after the assignment and perform the move automatically, but that might run counter to the desired change of having lifetimes controlled by their lexical scope. While the more flexible lifetime does leave open the possibility of a performance hit if someone later adds code that uses the local values without thinking, it's also consistent with a philosophy of progressive disclosure: "get the best or near-best results writing the most straightforward code, then be explicit if you need to be later".

Essentially, I hope we can avoid some of the pitfalls that C++ has, where trying to do what you think is "the right thing" ends up making things worse. For example, a C++ user new to move-semantics might think "I have a function that returns a large collection, but I'll return std::move(...) it so it doesn't make a copy!", but then they've gone and undone the return-value optimization. So while this philosophy is something I agree with:

...it would be even better if Swift can do the performant thing by default without any explicit expression of intent; that's what would set its memory model apart from other languages like C++ and Rust.

Whenever the compiler is able to infer something about memory lifetime automatically that could be expressed explicitly, maybe there could be a way for users to enable "educational notes" as optional diagnostics, and the compiler would flag all those inferences to let the user know "by the way, if you want to ensure that you don't make a change that could cause problems later, you can add move here" or something to that effect. Memory models can be tricky to master, and giving authors guided diagnostics about how they could be more explicit, even if they don't need to be with the code written as it is at the moment, is just as important as giving them error diagnostics when they do something wrong.

18 Likes