Hacker News new | ask | show | jobs
by pjmlp 1831 days ago
> This isn't representative of application code and there isn't even any mention of the metrics I mentioned…

Yeah, that is the usual answer when benchmarks prove how much urban myth reference counting performance is actually like.

> No it doesn't. I told you it didn't the last time you said this.

Did you?

There is more important stuff in life to store on my brain than a list of who replies to me on hacker news.

Anyway,

https://github.com/apple/swift/blob/main/stdlib/public/Swift...

https://twitter.com/ErrataRob/status/1331735383193903104

2 comments

> Yeah, that is the usual answer when benchmarks prove how much urban myth reference counting performance is actually like.

CPU/wall time benchmarks are not that relevant to system performance (seriously!) because second-order effects matter more. But if you had peak memory and page demand graphs that would matter.

For a network driver I don't know if it'd really look any different though. That's mostly arena allocations.

> https://twitter.com/ErrataRob/status/1331735383193903104

The fast atomics and JavaScript instructions do exist but aren't "special", they're just part of the ARM ISA.

Apple's atomics as of recently are almost magically fast, though.
Thanks for sharing these links! Super interesting. I do have a question though. The ixy benchmarks seem to imply that RC is generally slower then GC (go and C# are much faster then swift and are only outdone by languages with manual memory management).

However in the tweet thread you shared, the poster said

> all that reference counting overhead (already more efficient than garbage collection) gets dropped in half.

Implying that reference counting is actually more efficient. I don't know how to rectify these two observations. Do you have any insights?

The observation is done by point of view of Swift developers.

The only reason why Swift has reference counting was historical.

Objective-C GC implementation failed, because it was very hard to mix frameworks compiled with and without GC enabled, alongside the usual issues of C memory semantics.

https://developer.apple.com/library/archive/documentation/Co...

Check "Inapplicable Patterns" section.

So Apple did the right design decision, instead of trying to fix tracing GC in such environment, just like Microsoft does in COM, they looked into Cocoa [retain/release] pattern, automated that, and in a marketing swoop sold that solution as ARC.

Swift as Objective-C replacement, naturally had to build on top of ARC as means to keep compatibility with Objective-C runtime without additional overhead (check RCW/CCW for how .NET GC deals with COM).

Here is a paper about Swift performance,

http://iacoma.cs.uiuc.edu/iacoma-papers/pact18.pdf

> As shown in the figure, performing RC operations takes on average 42% of the execution time in client programs, and 15% in server programs. The average across all programs can be shown to be 32%. The Swift compiler does implement optimization techniques to reduce the number of RC operations similar to those described in Section 2.2.2. Without them, the overhead would be higher. The RC overhead is lower in server programs than in client programs. This is because server programs spend relatively less time in Swift code and RC operations; they spend relatively more time in runtime functions for networking and I/O written in C++.

It makes technical sense that Swift uses reference counting, as explained above, but it isn't due to performance, it just sells better than explaining it was due to Objective-C inherited C memory model, which besides the memory corruption problems, it doesn't allow for anything better than a conservative garbage collector, with very bad performance.

https://hboehm.info/gc/