I’ve recently seen two really nice and educating languages talks:
This first one by Herb Sutter, presents all the nice and cool features of C++0x, why C++’s future seems brighter than ever, and how M$ is said to be a good guy in this game. The talk revolves around efficiency and how minimizing heap activity very often improves performance.
This other one, by Andrei Alexandrescu, motivates a transition from C/C++ to his new game-changer D. Most of D’s stuff seems really well motivated and designed. One thing, however, surprised me, namely that D pushes for garbage collection and that all classes are created solely by reference. Even more confusing, the book The D Programming Language Ref Manual specifically in the section about Resource Management states the following, quote:
Garbage collection eliminates the tedious, error prone memory allocation tracking code
necessary in C and C++. This not only means much faster development time and lower
maintenance costs, but the resulting program frequently runs faster!
This conflicts with Sutter’s constant talk about minimizing heap activity. I strongly respect both Sutter’s and Alexandrescou’s insights, so I feel a bit confused about these two key questions
-
Doesn’t creating class instances solely by reference result in a lot of unnecesseary heap activity?
-
In which cases can we use Garbage Collection without sacrificing run-time performance?
To directly answer your two questions:
Yes, creating class instances by reference does result in a lot of heap activity, but:
a. In D, you have
structas well asclass. Astructhas value semantics and can do everything a class can, except polymorphism.b. Polymorphism and value semantics have never worked well together due to the slicing problem.
c. In D, if you really need to allocate a class instance on the stack in some performance-critical code and don’t care about the loss of safety, you can do so without unreasonable hassle via the
scopedfunction.GC can be comparable to or faster than manual memory management if:
a. You still allocate on the stack where possible (as you typically do in D) instead of relying on the heap for everything (as you often do in other GC’d languages).
b. You have a top-of-the-line garbage collector (D’s current GC implementation is admittedly somewhat naive, though it has seen some major optimizations in the past few releases, so it’s not as bad as it was).
c. You’re allocating mostly small objects. If you allocate mostly large arrays and performance ends up being a problem, you may want to switch a few of these to the C heap (you have access to C’s malloc and free in D) or, if it has a scoped lifetime, some other allocator like RegionAllocator. (RegionAllocator is currently being discussed and refined for eventual inclusion in D’s standard library).
d. You don’t care that much about space efficiency. If you make the GC run too frequently to keep the memory footprint ultra-low, performance will suffer.