4 ms·
Similarly, the statement > Reference counting also has its own running cost, paid on every copy of a pointer you make and every time you drop one. isn’t 100%
by Someone 2mo ago
Similarly, the statement
> Reference counting also has its own running cost, paid on every copy of a pointer you make and every time you drop one.
isn’t 100% true. It’s not necessarily on every copy or drop. Compilers can (and do) elide reference count updates if they can proof they aren’t needed, and can even skip allocating room for reference counts if they can proof it isn’t needed (example: a local object that doesn’t escape its scope)
I also find it a miss that the article doesn’t discuss memory usage. A garbage-collected program needs more memory to match the performance of the equivalent manually managed language.
https://dl.acm.org/doi/10.1145/1094811.1094836 https://dl.acm.org/doi/10.1145/1094811.1094836 says you need to give it 5 times the memory, but that’s from 2005 and likely outdated.
- kazinator 2mo agoIn 1990s C++ we did: void foo::method(const &smart_ptr<thing> x) { ... } The smart pointer passed reference isn't copy-constructed and so no refcount is bumped. It has a scoped lifetime. The calling function owns a reference (baseline correctness assumption or else we are screwed). That caller is suspended while the callee executes.
- deathanatos 2mo agoIt's still done. It's not uncommon to see that in Rust: fn foo(x: &Arc<T>) …quite literally borrows the count in the refcount-ed thing. I think you can find similar things in CPython, on the C side of things.
- pjmlp 2mo agoOnly if reference counting is exposed in the type system, or the standard library types are blessed to the compiler, otherwise there is no way for the compiler to know what to elide.
- hinkley 2mo agoBut you can also put generational GC on steroids by implementing escape analysis, which creates a separate category of allocations that don’t have to be marked and swept at all. Effectively they were marked the first time the code was run and never have to be marked again. What people forget too is that new and destroy in C++ aren’t exactly cheap either. As far back as Java 5 the hotspot people were bragging on how new in Java was cheaper than new in C++, closer to stack allocation speed. Of course if you look at any Java library other than ones intended for embedded or HFT systems, you will see Jevons’ Paradox at play. Made allocation cheap, and everyone allocates the hell out of everything, eating up the gains and then some. But at the same time, the architectural simplicity of not having to worry about object lifetimes makes APIs simpler, which allows people to invest that brain power into making them more sophisticated in other dimensions. Watching Rust try to get itself doubly linked lists was strange to watch from the bleachers.