4 ms·
Reference counting, even ignoring the additional expense C++ places on std::shared_ptr by requiring it be thread safe, is far too slow for allocation heavy lang
by gsg 13y ago
Reference counting, even ignoring the additional expense C++ places on std::shared_ptr by requiring it be thread safe, is far too slow for allocation heavy languages. Only "we don't give a damn" implementations (like CPython) use it, because it is simply not competitive.
- pcwalton 13y agoNot necessarily true. See "Down for the Count?" ISMM 2012: http://users.cecs.anu.edu.au/~steveb/downloads/pdf/rc-ismm-2012.pdf http://users.cecs.anu.edu.au/~steveb/downloads/pdf/rc-ismm-2...
- gsg 13y ago"This brings the performance of reference counting on par with that of a well tuned mark-sweep collector." I'm not really convinced. How well does it stack up when the competition is a copying generational collector?
- pcwalton 13y agoThey compare against a copying collector.
- pkolaczk 13y ago... implemented in Jikes RVM which is very far behind Oracle JVM. Herz and Berger (2005) based their experiment on Jikes RVM, too, and incorrectly concluded that GC needs 5x more memory to have acceptable performance comparable to malloc/free. Someone else redid their experiments using Oracle JVM and it turned out that it was not 5x, but 20%.
- a8da6b0c91d 13y agoshared_ptr may be slow (I don't know) but you actually make very little "garbage" in C++, so it's not a problem. You're simply forced by the language to have clear ownership of resources most of the time.
- comex 13y agoThis, and if you're using shared_ptr heavily in C++, you're probably doing it wrong, since unique_ptr is usually sufficient. (You could say that shared_ptr has the advantage that you don't have to think about who owns what, but with C++ there's no way around doing some amount of thinking about that, lest you get cycles.)
- gsg 13y agoThat's a reasonable defense of std::shared_ptr, but I was not discussing C++ code (I was careful to mention "allocation heavy languages" in my post).
- dilap 13y agoObjective-C uses ref counting and does alright... Hardly a language that doesn't prioritize performance.
- comex 13y agoObjective-C, a language which uses dynamic dispatch for all method calls and does not do any kind of type-specialized code generation, certainly does not prioritize performance.
- millstone 13y agoIt priorities performance in one important respect: by providing direct access to C. It's common in many languages to write performance critical sections in C or even assembly. This is trivial in ObjC, which has C as a subset, so it is done more often than in e.g. Python or Java. Interoperability with FFIs is one of the advantages of reference counting over GC. You don't have to worry about pinning allocations, allocation coloring, unscanned roots, etc. The ObjC refcounting operations (CFRetain/CFRelease), and the collection types (CFArray, CFString, CFSet...) are all trivially available from C as well. I speculate that this better interoperability with C is why Apple deprecated GC and went with ARC. We can see Microsoft sort of moving in the same direction with WinRT.
- dilap 13y agoI guess the phrase "prioritize performance" is maybe ambiguous. It's a language that cares a lot about performance, let's say -- sure, it uses dynamic dispatch for its method calls (losing a little speed compared more-static C++ virtual methods, which themselves lose a little speed compared to non-virtual methods), but the implementation itself is very optimized (there's some good blog articles describing the implementation, but I don't have them at hand), and you always have normal function calls as in C if you need maximum speed (as millstone mentioned). C really feels like a first-class language when using Objective-C, and C is a pretty damn fast language. (As an aside, there was an optional GCed variant of objective-c around for a while. Not sure what the performance impact was vs ref counted.)
- praseodym 13y agoiOS uses Automatic Reference Counting (ARC, http://en.wikipedia.org/wiki/Automatic_Reference_Counting http://en.wikipedia.org/wiki/Automatic_Reference_Counting) by having the compiler add reference counting instructions, while refraining from having the developer add tedious reference counting instructions themselves. I'm not sure if there are significant performance advantages over proper GC. It's worth noting that Apple has implemented GC in Objective-C on OS X before, but deprecated that in favour of its ARC implementation -- probably because its garbage collection implementation was no good at all (performance-wise).
- do-it-good 13y agoiOS is a technology swamp.
- pjmlp 13y agoApple dropped GC in Objective-C, because they never managed to make it work properly. By the time ARC was announced, there were still lots of corner cases in the ways code compiled with GC was interacting with code that wasn't compiled with GC enabled. Plus, if you check Apple's developers documentation from those days, great care was required to make sure the GC could play nice with the C part of Objective-C. So, in reality the ARC approach was taken, because it was the only way to have a working automated memory management, compatible with Objective-C code overall. Of course, being Apple, they sold it as a better solution for memory management and not as a result from their failure to implement a sound GC for Objective-C.
- nly 13y agostd::shared_ptr is not thread safe, only the control block shared between all of the std::shared_ptr objects is thread safe. This means you only get a locking penalty when shared_ptr objects are constructed, copied, or destroyed, but not moved, dereferenced, or casted. Both construction and destruction will allocate or can release memory, respectively, which I would think would bottleneck before any atomics or memory barriers inside shared_ptr. To me, the first likely port of call for improving performance in these cases is therefore a custom memory allocation strategy like a memory pool. Copying can be a concern, but most containers and standard algorithms should be move aware now. You should be moving shared_ptr's far more often than you copy them. All that aside, thread-safe by default seems to be the sane decision in this era.