Monday, December 12, 2022

The Swifty Future of Foundation

Tony Parker (tweet):

The swift-corelibs-foundation project helped launch the open source Swift version of Foundation in 2016, wrapping a Swift layer around the preexisting, open source C implementation of Foundation.

[…]

Today, we are announcing a new open source Foundation project, written in Swift, for Swift.

[…]

With a native Swift implementation of Foundation, the framework no longer pays conversion costs between C and Swift, resulting in faster performance.

[…]

Multiple implementations of any API risks divergent behavior and ultimately bugs when moving code across platforms. This new Foundation package will serve as the core of a single, canonical implementation of Foundation, regardless of platform.

[…]

Open source projects are at their best when the community of users can participate and become a community of developers. A new, open contribution process will be available to enable all developers to contribute new API to Foundation.

This sounds great. My understanding is that Foundation started as Objective-C and was re-written for Mac OS X to wrap Core Foundation, where possible—much like swift-corelibs-foundation wraps CF in Swift. This added some overhead but unified the implementations. Since then, Foundation has been rewritten back into Objective-C, which made it faster. Now, it sounds like the plan is to rewrite it in Swift and extend Swift to allow Objective-C to call the Swift implementation of the old API.

Tony Parker:

We’ve prototyped this approach and are pretty sure it will work out well. A reimplementation of Calendar in Swift is 1.5x to 18x as fast as the C one (calling from Swift in various synthetic benchmarks like creation, date calculation). And it’s completely compatible with the existing C and ObjC entry points, too.

David Smith:

This means that now

  • Foundation has the option to use a memory safe language internally
  • Most system components that Foundation depends on have the option to use a memory safe language internally
  • Embedded environments like the Secure Enclave can use Swift
  • Pure-Swift processes use less memory
  • Swift Strings use less memory and are faster
  • Swift WebAssembly programs can be much smaller to download
  • NSString<->String bridging can use Foundation/CoreFoundation internals directly, resulting in some speedups

Tony Parker:

Many of Foundation’s features have been subsumed by direct support in the language. These types are currently not planned to be brought forward into the new package[…] On Darwin, the Foundation framework will continue to maintain implementations for these types in a combination of C, Objective-C and Swift.

It’s seems somewhat undetermined what the plan is for functionality in the old types that is not available elsewhere.

Previously:

Update (2023-01-12): See also: Sergio De Simone (via Hacker News).

9 Comments RSS · Twitter

Walter rawdanik

Claims that Swift ( or Java or C# or whatever ) implementations of particular feature are
faster than equivalent C implementation just don’t make sense given that Swift itself is written in C++.
It is pretty much always case of comparing some kind of inferior algorithm implementation to something more optimized algorithimically.

@Walter I haven’t seen exactly what they are comparing here, but in the case of Calendar I think the algorithmic stuff is in ICU in both cases, so it may be that there is less overhead calling from Swift, e.g. because they can just pass in the pointer to a Swift String’s UTF-8 storage instead of transcoding a CFStringRef.

@Walter:
"Claims that Swift ( or Java or C# or whatever ) implementations of particular feature are faster than equivalent C implementation just don’t make sense given that Swift itself is written in C++."

That argument doesn't make sense to me. Even if Swift compiler were written in Python, and that wouldn't affect the performance of the compiled code.

(I don't actually think that Swift compiles to noticeable faster code than C. However, in theory it could happen that some Swift language constructs are difficult to map to C, and that results in slowdowns when you try to express some behavior in C. More likely, as @Michael notes, the actual advantage is that impedance mismatches are avoided at interfaces.)

Pierre Lebeaupin

Also, the C++ aspect of the Swift toolchain has little relevance here: the Swift compiler may be overwhelmingly in C++ (and LLVM entirely so, of course), but this is beside the point as those don't run as part of the benchmark (e.g. in cross-compilation they run on the build machine, not the target).

The Swift standard library, on the other hand, is implemented in Swift. Well, a Swift dialect that has access to raw memory arrays and other facilities (not entirely unlike unsafe Rust), but you get the drift.

Many libraries, including CryptoKit, (a large part of) Foundation, Combine, are not related to system API directly. Apple has open-source version of them but uses another close one on their platforms (Combine is not open-source, but there's https://github.com/OpenCombine/OpenCombine). While Microsoft chooses to use the same new .NET Core implementation across Windows, Linux, macOS, etc.

And if they want, SwiftUI can also be open-sourced to leverage public AppKit/UIKit API. I think Windows's new WinUI 3 goes such approach.

@Daveed @Pierre I imagine that @Walter was referring to the fact that the Swift runtime is implemented in C++.

Pierre Lebeaupin

Thanks, I thought the C++ parts of the runtime were limited to things like ARC and hadn’t noticed that such a significant part of the Swift core library (to top it off, it’s a language that heavily blurs the distinction between core language features and standard library functionality) was in C++; possibly because that code hasn’t shown much in my profiling (a lot of this functionality is also implemented in the compiler so it can be and often is emitted inline and then subject to optimizations). Maybe that’s what they ought to rewrite in Swift first, instead of subjecting non-Swift programs to transitively including the Swift libraries through Foundation…

As usual, the language is carefully confusing in order to make Swift look good.

" is 1.5x to 18x as fast as the C one (calling from Swift in various synthetic benchmarks like creation, date calculation)"

This looks like the Swift implementation is 1.5x to 18x as fast as the C one. But wait, what's that in parentheses?

"calling from Swift"

Of course putting that in parentheses deliberately makes it look like that's a minor, irrelevant detail. But I bet it's not. I am quite certain that the new Swift implementation is 1.5x to 18x as fast *only* when calling from Swift, because any material speed advantage will come exclusively from eliminating bridging.

@Marcel Yep, though I doubt that they are trying to be confusing. I mean, the context of the announcement is “no longer pays conversion costs.” Swift created the problem and then solved it by rewriting the stuff it touched. Still, it’s good news compared with the status quo.

Leave a Comment