On 24.10.2011 5:57, Sean Silva wrote:
== Quote from Dmitry Olshansky (dmitry.o...@gmail.com)'s article
Less efficient is a moot point.
When you do iteration and other stuff you'd use range, like you'd
use
iterators in c++. Range gets stack/register allocated pointers
directly
to data (or close to it, that depends on container) so the only
extra
cost in reference type compared to value is the first indirect
access to
construct range and it's negligible.

The problem isn't the speed of iteration, it's the extra heap traffic
that is involved. I mean, for you average app this isn't going to
matter; those are the apps that can just as easily be written in
Java/C#. But it can be a problem for serious systems code (the kind
that is pretty much always written in C/C++).

While we are going into very specialized territory, I must note that there would never be a clear winner in this battle. E.g. null reference saves you from one nice overhead - default initialization / checking for it. And while it was some time ago, I do remember that some std vectors preallocated space on *heap* for around 10 elements, this might not be true now, of course.


For example, if you look in the LLVM source tree, you'll see that they
bend over backwards to avoid heap allocations. For example, in some
cases, std::vector causes too much heap traffic so they have
SmallVector which preallocates a certain amount of storage *inside* of
the object itself in order to avoid heap traffic if the number of
elements doesn't exceed some predetermined amount.

Like I said before you can place class instances wherever you want to, in this case it's most likely a pool or free list, stack space. The only difference is that manual memory management is not that common in D yet and is fully explicit, done on case by case basis ( no class allocators etc. ). And "small string optimization" also is not going away, that's for sure. Seeing that you are concerned by memory layouts and such, you might as well add some thought power to push forward allocators design. IIRC David Simcha is working on a version 2 proposal for it.

Even still, LLVM
uses std::vector all over the place, and it I've never seen a
std::vector embedded in a class by reference; it is always held by
value precisely because then you don't do an unnecessary heap
allocation.

And let me guess these objects are passed by... reference? And why? - because they are too big value types, that sort of defeats the value type doctrine here.


I'm positive that if std::vector involved a heap allocation for the
vector object itself, llvm would basically have rewritten a heap-less
vector object, just like they have done in the more extreme case for
SmallVector. But the thing is that in D, it is possible to write an
easy-to-use vector for which it is a one-liner to switch between GC
heap-allocated vector object, by-value vector, preallocated internal
vector (like SmallVector), and beyond!

I note that heap/no heap is completely orthogonal matter, the default is however safe and reasonably fast. And IMO changing storage most of the time involves some work behind the scenes to get it as "one-liner".


I admit, I'm very biased because my use case for D is low-level
systems programming a la C/C++, so naturally I want a standard library
that will not compromise on aspects that are important for the kinds
of programs that I write. Nonetheless, if the goal is to have "good
enough" containers, then it doesn't matter, but if the goal is to have
"truly optimal" containers (as I think it should be; D is certainly
powerful enough to pull it off elegantly), then it does matter.

Aye, being a C++ turncoat myself I can understand this sentiment ;)

--
Dmitry Olshansky

Reply via email to