Re: placement new
On Sep 10, 9:56 pm, Andre Kostur <nntps...@kostur.net> wrote:
karthikbalaguru <karthikbalagur...@gmail.com> wrote innews:1189448979.583=
628.172020@o80g2000hse.googlegroups.com:
I find that articles stating that 'placement new' constructs
an object on a pre-allocated buffer and so takes less time.
Don't waste your time with such articles. The authors obviously
don't know what they are talking about.
Depends on what you're trying to measure. Yes, 'placement new' is
faster than a simple 'new'. But that's because 'new' has to do more
work.
Yes and no. Regretfully, the term "placement new" doesn't
really mean what one would expect. It refers to any new
expression which has additional arguments, and which thus calls
a placement new allocation function. So:
T* p = new T ;
// calls: operator new( sizeof( T ) )
T* p = new ( pool ) T ;
// calls operator new( sizeof( T ), pool )
(In both cases, after calling the allocation function, it then
calls the constructor of T.) Obviously, the total runtime will
depend somewhat on the execution time of the allocator function
(which has the name "operator new", just to add to the
confusion) called. The standard defines several placement new:
T* p = new (std::nothrow) T ;
// calls operator new( sizeof(T), std::nothrow)...
// which returns a null pointer instead of raising
// std::bad_alloc in case of failure.
char* buffer ;
T* p = new ( buffer ) T ;
// calls operator new( sizeof(T), buffer )...
// if <new> has been included, and no other
// operator new functions have been declared,
// overload resolution will choose the standard
// operator new( size_t, void* ) function. Which
// is defined to return the second argument, no
// questions asked.
It is the second which one usually thinks of when placement new
is talked about, because it ends up doing very much what the
name "placement new" suggests. The mechanism is far more
general, however, and this last form ends up calling the
constructor at a pre-determined address only because the
semantics of the allocator function are so defined.
Of course, it's hard to imagine a system where just returning
the address wouldn't be faster than actually allocating memory,
but this is really irrelevant. The two operations have
completely different semantics, and you can't simply replace one
with the other, in order to speed up your program. The choice
of which one to use must be based entirely one the needed
semantics.
In the case of this last "placement new", it is normally used
whenever you want allocation and initialization separated, i.e.
to occur at a different time. I can think of at least two cases
where this is important: in containers, where you want a
contiguous block of elements, but you don't have the information
necessary to initialize them all immediately (e.g. as in
std::vector), and in implementations of discriminate unions, if
you wanted to support objects with non-trivial constructors or
destructors (boost::variant, perhaps).
Actually, we have to consider the allocation of the buffer
and then the construction of object using 'placement new'.
So, Effectively it should be taking more time . What do you
think ?
That's a different question. And it might be faster and it
might be slower. Depends on what you're doing to allocate the
buffer. Your own allocator may or may not be faster than the
"default" allocator.
It would be surprizing if it were faster than the default
operator new( size_t, void* ):-).
[...]
So, How could 'placement new' be stated to be faster ?
Anything can be stated when the author doesn't know what he is
talking about.
Because you're not looking at the whole question. If you already have
the memory block through some other mechanism, then you don't need to
spend time talking to the global allocator to get more memory.
And you're addressing the problem backwards. If you have the
memory block through some other mechanism, you can't use any
other form of new, because no other form will have the correct
semantics.
Further, what is the advantage in using 'placement new'. It in turn is
depending on the pre-allocated buffer in heap that is assigned using
'new'. So, how does 'placement new' prove to be good in comparison
No.. the pre-allocated buffer may not be in heap.... neither does it
necessarily come from new.
But watch out for alignment problems if it doesn't.
with 'new' as it indirectly depends on heap ?
Why was 'placement new' introduced in c++ ? What are the practical
areas of application of 'placement new' ?
How about: I want to construct an object in a shared memory segment (Ok,
this bit is somewhat offtopic). I can't use the normal new since it
isn't allocated off of the heap. So I use whatever the allocation
method is for the shared memory segment and then use placement new to
construct the object in that memory block.
Rather, what I use is placement new directly:
T* p = new (sharedMemoryPool) T ;
Or look at many implementations of vector. It will have allocated some
chunk of memory for all of the current objects in the vector, plus some
more for some future objects (Probably. This is why capacity() doesn't
necessarily equal size().).
There's no probably about it: the standard requires that the
number of copies be an amortised constant for insertions at the
end. Reallocation means copying all existing objects, so some
exponential strategy of growth must be used.
But the issue of separating allocation from initialization goes
further, and affects more than just performance. As a user, I
can, for example, do v.reserve( 100 ), and be assured that my
iterators into the vector are valid as long as I don't insert
more than a hundred elements. While speed was probably also a
consideration in this particular case (you don't want to recopy
a million elements each time you append one), there are also
significant semantic issues. Independantly of speed
considerations, the semantics of std::vector require separation
of allocation and initialization. (In fact, because the user
can instantiation any standard container over his own, custom
allocator, all standard containers require separation of
allocation and initialization.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34