You won't see many clones in rust code.
Also it'd be nice if the reference counts were stored separately from the objects. Storing them alongside the object being tracked is a classic mistake made by reference count implementations (it spreads the writes over a large number of cache lines). I was actually surprised that Rust doesn't get this right.
Another issue with manual memory management is that you can't compact the heap.
Yes in theory it would be more efficient to store all the reference counts together, but that's in theory. In practice most Rust apps will not call clone on a shared pointer on a hot path and if they do it's usually 1 such pointer and they do something with the data as well (so it's all 1 cache line anyway)
You can't compare Rust/C++ with Swift/Nim when it comes to RC, there just aren't enough reference count operations for it to matter much (unless you're in a shitty OO C++ codebase like me that pretends it is java with std::shared_ptr everywhere)
Apps where heap compaction would be relevant in a low-level language like Rust or C++ will typically use a bump allocator which will trounce any kind of GC.
Naturally if the purpose was to compare stack allocation performance other approach would have been taken.
Apparently the ARC performance improvements announced at WWDC 2022 weren't needed.
Nor is wallclock speed even what the system should be optimizing for, since you buy phones to run apps not to run the system. You should be measuring how well it gets out of the way of the important work.
"Fast. Swift is intended as a replacement for C-based languages (C, C++, and Objective-C). "
-- https://www.swift.org/about/
"From its earliest conception, Swift was built to be fast. Using the incredibly high-performance LLVM compiler technology, Swift code is transformed into optimized machine code that gets the most out of modern hardware. The syntax and standard library have also been tuned to make the most obvious way to write your code also perform the best whether it runs in the watch on your wrist or across a cluster of servers.
Swift is a successor to both the C and Objective-C"
Also do traces not have to work atomically? The program needs to stop, you can’t have it check roots as it runs.
I’ll admit I am no GC researcher with ph.D experience, but your comment makes it seem you aren’t either.
Atomics are handy in a parallel/multi-core tracing collector, but IME pointer chasing in tracing somehow manages to cover the time it takes to do atomic operations.