It's like Rust in that it offers memory safety by default without a big performance hit.
It's like Rust in that it offers memory safety by default without a big performance hit.
Chris Lattner (of LLVM fame) did design the language with the goal of hiding complexity until it is needed.
> The concept of progressive disclosure in Swift, where you can start with something very simple and then learn complexity as you go, was totally driven by making it teachable. I personally spent a lot of time trying to make sure that the introduction to Swift could just be print("Hello World"). No semicolons, no \ns, none of that public static void main stuff. Making it simple and approachable was a strong goal, and not in a weird way where in a teaching environment there is this “Swift Prime” language that’s similar but different.
https://oleb.net/blog/2017/06/chris-lattner-wwdc-swift-panel...
You might be surprised (I was). Most of the benchmarks I’ve seen place it more in the neighborhood of golang and v8, rather than the C, C++, rust neighborhood you might expect.
Another commenter in this thread highlighted that the ref-counting GC is what keeps it out of the C / Rust performance neighborhood.
So not even sure that GC has always a perf cost is always true.
Not saying it doesn't in some cases, just so that we are clear but the truth seems to be more nuanced.
Apple has been writing OS components in Swift for a while now. It certainly doesn't seem to be producing the performance issues we saw when Google attempted to write components for Fuchsia in Go or Microsoft's effort to create new features for Longhorn in .NET.
My experience with Swift is somewhat limited, because every time I've tried to use it, I've run into glaring performance issues and had to switch language. It might be reasonably performant compared to Go or .NET, but it's nothing like Rust.
Do you have a reference somewhere I can read up?
Add a little bit of salt to insult you need it to be atomic if you want it to run on SMP. This means for each time you have create/release the lifetime of an object you will make a lot of memory barriers, and create a lot of cache contention.
But in practice the overhead is actually nought, and most of the time you rather deal with I/O bound problem more than an additional atomic increment operation. Modern processor is fast enough to deal with them in few cycles in around the order of 10 nanoseconds
Hopefully the upcoming ownership functional will help in those cases.
Most of the time it’s possible to avoid atomic instructions and still be thread-safe. https://dl.acm.org/doi/10.1145/3243176.3243195:
“BRC is based on the observation that most objects are only accessed by a single thread, which allows most RC operations to be performed non-atomically. BRC leverages this by biasing each object towards a specific thread, and keeping two counters for each object --- one updated by the owner thread and another updated by the other threads. This allows the owner thread to perform RC operations non-atomically, while the other threads update the second counter atomically. We implement BRC in the Swift programming language runtime, and evaluate it with client and server programs. We find that BRC makes each RC operation more than twice faster in the common case. As a result, BRC reduces the average execution time of client programs by 22.5%, and boosts the average throughput of server programs by 7.3%.”
I remember reading that this made it into Swift, but cannot find it, so I’m not sure anymore.
And of course, the Swift compiler tries to avoid unnecessary refcount updates.
According to information released when the M1 came out: retaining and releasing an NSObject takes ~30 nanoseconds on current gen Intel, and ~6.5 nanoseconds on an M1
(or if going with BRC, correspondingly there shouldn't be a advantages for this custom CPU feature)
So they went with plan B, having the compiler automate the retain/release messages used by the Cocoa framework.
Everywhere else in Objective-C, the memory is still manually managed, or via memory pools.