Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   pImpl idiom: Heap vs Stack (http://www.velocityreviews.com/forums/t745471-pimpl-idiom-heap-vs-stack.html)

Hoyin 03-21-2011 10:32 AM

pImpl idiom: Heap vs Stack
 
I am reading an notes about Pointer To Implementation (pImpl) Idiom
which is trying to decouple the interface and impl via a pointer e.g.

class Book
{
public:
void print(){m_p->print()};
private:
class BookImpl;
BookImpl* m_p;
};

class BookImpl // in a separated file
{
public:
void print();
private:
std::string m_Contents;
std::string m_Title;
};

which avoid re-compile on the client code if we want to add/remove
property for Book (we change class BookImpl's data member rather than
class Book), BUT, in most case, the obj of BookImpl will be allocated
in Heap rather than Stack. Will there be significant cost introduced
by this change (we will be accessing the data from Heap instead of
Stack)? I was told accessing data from Heap is less efficient than
from Stack (even thought we have pointers/address to those memory) but
why? How we can measures the cost introduced? thanks

Hoyin

puppi 03-21-2011 11:22 AM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 7:32*am, Hoyin <haoxian.z...@gmail.com> wrote:
> I am reading an notes about Pointer To Implementation (pImpl) Idiom
> which is trying to decouple the interface and impl via a pointer e.g.
>
> class Book
> {
> public:
> * void print(){m_p->print()};
> private:
> * class BookImpl;
> * BookImpl* m_p;
>
> };
>
> class BookImpl // in a separated file
> {
> public:
> * void print();
> private:
> * std::string *m_Contents;
> * std::string *m_Title;
>
> };
>
> which avoid re-compile on the client code if we want to add/remove
> property for Book (we change class BookImpl's data member rather than
> class Book), BUT, in most case, the obj of BookImpl will be allocated
> in Heap rather than Stack. Will there be significant cost introduced
> by this change (we will be accessing the data from Heap instead of
> Stack)? I was told accessing data from Heap is less efficient than
> from Stack (even thought we have pointers/address to those memory) but
> why? *How we can measures the cost introduced? thanks
>
> Hoyin


I will restrict my considerations to the x86 family of processors
(essentially, 32 and 64 intel and intel-compatible processors, except
for the discontinued intel's Itanium processor). I suspect there is
some generality to what I'm saying, but I can't safely say that it
will all hold exactly for other processor architectures (such as the
ARM architecture, common in smartphones).
That being said, and assuming that you know what an offset is: every
processor has registers, which are, grosso modo, a region of memory
inside the CPU with very fast access time (much faster than RAM). When
you have a local variable, its address is known at compile time as an
offset to a register known as the base pointer. Hence the address of
local variables can be computed very quickly: it suffices to add some
compile time constant to a register. If a local variable is composite,
such as an object, and since object members addresses are defined at
compile time as offsets to the object's address (the exact offset
being implementation dependant), the compiler just adds the member's
offset to the object's offset (from the base pointer) to compute the
member's address (relative to the base pointer), allowing very fast
access to members. If an object is stored dynamically instead, first
the pointer's address must be obtained (which is a compile time
constant for static allocation, an offset to base pointer for
automatic allocation, i.e. if it is local), then its contents must be
fetched from memory, and then these contents, the address of the
object, are used to compute the member's address. The difference in
efficiency between a local object and a dynamically allocated object
is that of a memory access (in RAM), plus a possible register-level
addition (which has a dismissable cost compared to the memory access).
That usually doesn't mean much as an absolute time cost, except for
member's used very frequently in places such as loops.
However, if you access a dynamically allocated objects frequently in a
portion of code, a decent compiler (with optimized compilation) will
only fetch the object's address once and place it in a register. From
that point on, the access times for the members will be the same as if
it were allocated in the stack. This is why you shouldn't worry too
much about the extra time cost for your implementation: they will only
really cost you if you don't use a decent compiler.

Juha Nieminen 03-21-2011 12:26 PM

Re: pImpl idiom: Heap vs Stack
 
Hoyin <haoxian.zhao@gmail.com> wrote:
> which avoid re-compile on the client code if we want to add/remove
> property for Book (we change class BookImpl's data member rather than
> class Book), BUT, in most case, the obj of BookImpl will be allocated
> in Heap rather than Stack. Will there be significant cost introduced
> by this change (we will be accessing the data from Heap instead of
> Stack)?


It depends on how much you instantate the class in question (and how).

If you create, for example, a vector containing a million instances of
your class, the difference (in the creation time) could be quite
significant (one million one allocations for the PImpl version vs. one
single allocation for the non-PImpl version, and memory allocation can
be a relatively heavy operation). Memory consumption will also increase
with the PImpl version.

Goran 03-21-2011 01:05 PM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 11:32*am, Hoyin <haoxian.z...@gmail.com> wrote:
> I am reading an notes about Pointer To Implementation (pImpl) Idiom
> which is trying to decouple the interface and impl via a pointer e.g.
>
> class Book
> {
> public:
> * void print(){m_p->print()};
> private:
> * class BookImpl;
> * BookImpl* m_p;
>
> };
>
> class BookImpl // in a separated file
> {
> public:
> * void print();
> private:
> * std::string *m_Contents;
> * std::string *m_Title;
>
> };
>
> which avoid re-compile on the client code if we want to add/remove
> property for Book (we change class BookImpl's data member rather than
> class Book), BUT, in most case, the obj of BookImpl will be allocated
> in Heap rather than Stack. Will there be significant cost introduced
> by this change (we will be accessing the data from Heap instead of
> Stack)? I was told accessing data from Heap is less efficient than
> from Stack (even thought we have pointers/address to those memory) but
> why? *How we can measures the cost introduced?


Is there a cost: yes, absolutely.

Is it significant: bad question. Answer depends very much on how
1. much speed you need
2. what are your call patterns
3. what your implementation (new/delete pair, mostly) and hardware
give you,

How to measure: make two versions (pimpl/"direct") of your code and
measure in an __optimized__ (by the compiler) build.

In C++, an abstract base class is a viable alternative to pimpl. Check
out http://stackoverflow.com/questions/8...lass-interface

Goran.

Hoyin 03-21-2011 01:55 PM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 11:22*am, puppi <fabricio.pu...@gmail.com> wrote:
> On Mar 21, 7:32*am, Hoyin <haoxian.z...@gmail.com> wrote:
>
>
>
>
>
>
>
>
>
> > I am reading an notes about Pointer To Implementation (pImpl) Idiom
> > which is trying to decouple the interface and impl via a pointer e.g.

>
> > class Book
> > {
> > public:
> > * void print(){m_p->print()};
> > private:
> > * class BookImpl;
> > * BookImpl* m_p;

>
> > };

>
> > class BookImpl // in a separated file
> > {
> > public:
> > * void print();
> > private:
> > * std::string *m_Contents;
> > * std::string *m_Title;

>
> > };

>
> > which avoid re-compile on the client code if we want to add/remove
> > property for Book (we change class BookImpl's data member rather than
> > class Book), BUT, in most case, the obj of BookImpl will be allocated
> > in Heap rather than Stack. Will there be significant cost introduced
> > by this change (we will be accessing the data from Heap instead of
> > Stack)? I was told accessing data from Heap is less efficient than
> > from Stack (even thought we have pointers/address to those memory) but
> > why? *How we can measures the cost introduced? thanks

>
> > Hoyin

>
> I will restrict my considerations to the x86 family of processors
> (essentially, 32 and 64 intel and intel-compatible processors, except
> for the discontinued intel's Itanium processor). I suspect there is
> some generality to what I'm saying, but I can't safely say that it
> will all hold exactly for other processor architectures (such as the
> ARM architecture, common in smartphones).
> That being said, and assuming that you know what an offset is: every
> processor has registers, which are, grosso modo, a region of memory
> inside the CPU with very fast access time (much faster than RAM). When
> you have a local variable, its address is known at compile time as an
> offset to a register known as the base pointer. Hence the address of
> local variables can be computed very quickly: it suffices to add some
> compile time constant to a register. If a local variable is composite,
> such as an object, and since object members addresses are defined at
> compile time as offsets to the object's address (the exact offset
> being implementation dependant), the compiler just adds the member's
> offset to the object's offset (from the base pointer) to compute the
> member's address (relative to the base pointer), allowing very fast
> access to members. If an object is stored dynamically instead, first
> the pointer's address must be obtained (which is a compile time
> constant for static allocation, an offset to base pointer for
> automatic allocation, i.e. if it is local), then its contents must be
> fetched from memory, and then these contents, the address of the
> object, are used to compute the member's address. The difference in
> efficiency between a local object and a dynamically allocated object
> is that of a memory access (in RAM), plus a possible register-level
> addition (which has a dismissable cost compared to the memory access).
> That usually doesn't mean much as an absolute time cost, except for
> member's used very frequently in places such as loops.
> However, if you access a dynamically allocated objects frequently in a
> portion of code, a decent compiler (with optimized compilation) will
> only fetch the object's address once and place it in a register. From
> that point on, the access times for the members will be the same as if
> it were allocated in the stack. This is why you shouldn't worry too
> much about the extra time cost for your implementation: they will only
> really cost you if you don't use a decent compiler.


Thanks Puppi, so basically the "extra" cost is from that we have to
compute the address (the offset from base pointer) of the heap object
on the fly rather than at compile time? what the registers (memory
inside CPU provide fast access time) is storing? the addresses of
local objects we computed at compile time? So there will be no
efficiency difference in access two objects in Heap/Stack if we can
(assume we can) know the offsets (against the base pointer) of the two
objects at compile time? thanks

Hoyin

robertwessel2@yahoo.com 03-21-2011 03:40 PM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 6:22*am, puppi <fabricio.pu...@gmail.com> wrote:
> I will restrict my considerations to the x86 family of processors
> (essentially, 32 and 64 intel and intel-compatible processors, except
> for the discontinued intel's Itanium processor).



IPF may not be doing all that well, but it's most certainly not
discontinued (in fact a major new CPU is on the way).

Noah Roberts 03-21-2011 04:24 PM

Re: pImpl idiom: Heap vs Stack
 
On 3/21/2011 3:32 AM, Hoyin wrote:
> Will there be significant cost introduced
> by this change (we will be accessing the data from Heap instead of
> Stack)? I was told accessing data from Heap is less efficient than
> from Stack (even thought we have pointers/address to those memory) but
> why? How we can measures the cost introduced?


With a profiler. If it indeed turns out that that there's too much
space or time being used up by the pimpl you can always push it back
into the open, close the firewall, and the cost is gone. You'll still
have a better design.

Unless you have real data associated with the profiling of your code, I
wouldn't even bother considering the opinions of those worried about
micro-optimizations. 99.99999% of the time they can be safely ignored.

--
http://crazycpp.wordpress.com

James Kanze 03-22-2011 12:25 AM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 12:26 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Hoyin <haoxian.z...@gmail.com> wrote:
> > which avoid re-compile on the client code if we want to add/remove
> > property for Book (we change class BookImpl's data member rather than
> > class Book), BUT, in most case, the obj of BookImpl will be allocated
> > in Heap rather than Stack. Will there be significant cost introduced
> > by this change (we will be accessing the data from Heap instead of
> > Stack)?


> It depends on how much you instantate the class in question (and how).


> If you create, for example, a vector containing a million instances of
> your class, the difference (in the creation time) could be quite
> significant (one million one allocations for the PImpl version vs. one
> single allocation for the non-PImpl version, and memory allocation can
> be a relatively heavy operation). Memory consumption will also increase
> with the PImpl version.


And locality could decrease, with negative impact even after the
allocation. If the class is small (e.g. something like complex
or Point), and you expect to have vectors with millions of them,
the compilation firewall idiom is not indicated. For a large
number of larger classes, however, it could be. On the other
hand, such larger classes are likely to be entity classes, which
can easily be constructed using a factory method, and then only
accessed through a pointer to the abstract base class. Which
accomplishes more or less the same thing as the compilation
firewall idiom.

So there's no general rule. You use whatever is most
appropriate for your application.

--
James Kanze

Öö Tiib 03-22-2011 01:37 AM

Re: pImpl idiom: Heap vs Stack
 
On Mar 21, 3:05*pm, Goran <goran.pu...@gmail.com> wrote:
> On Mar 21, 11:32*am, Hoyin <haoxian.z...@gmail.com> wrote:
>
>
>
>
>
> > I am reading an notes about Pointer To Implementation (pImpl) Idiom
> > which is trying to decouple the interface and impl via a pointer e.g.

>
> > class Book
> > {
> > public:
> > * void print(){m_p->print()};
> > private:
> > * class BookImpl;
> > * BookImpl* m_p;

>
> > };

>
> > class BookImpl // in a separated file
> > {
> > public:
> > * void print();
> > private:
> > * std::string *m_Contents;
> > * std::string *m_Title;

>
> > };

>
> > which avoid re-compile on the client code if we want to add/remove
> > property for Book (we change class BookImpl's data member rather than
> > class Book), BUT, in most case, the obj of BookImpl will be allocated
> > in Heap rather than Stack. Will there be significant cost introduced
> > by this change (we will be accessing the data from Heap instead of
> > Stack)? I was told accessing data from Heap is less efficient than
> > from Stack (even thought we have pointers/address to those memory) but
> > why? *How we can measures the cost introduced?

>
> Is there a cost: yes, absolutely.
>
> Is it significant: bad question. Answer depends very much on how
> 1. much speed you need
> 2. what are your call patterns
> 3. what your implementation (new/delete pair, mostly) and hardware
> give you,
>
> How to measure: make two versions (pimpl/"direct") of your code and
> measure in an __optimized__ (by the compiler) build.


Also things should be measured for real application, not some
hypothetical "create them a billion" tests. Pimple's state is cheap to
swap and to move, (just a single pointer) so for certain algorithms it
may even result with performance gain. Usually however the difference
does not affect performance since the bottle-necks tend to be in slow
I/O, in crappy concurrency and synchronization or in wasteful
algorithms.

> In C++, an abstract base class is a viable alternative to pimpl. Check
> out http://stackoverflow.com/questions/8...lass-interface


I have to disagree. People use these two things for different goals in
C++. It is very good that C++ supports such wide variety of idioms so
good designer can pick exactly fitting tool for each situation. These
two idioms do not overlap enough to alternate i think.

Pimple is fully implemented class with well-hidden and fire-walled
inner structure. That makes it useful as (non-abstract) base class or
as data member ... in OOP terms as generalized parent or as component
or element. In short ... like a value with functionality. Viable
alternative is just usual class without such firewall, abstract
interface does not cut it.

Abstract interface is a set of function descriptions that form an
interface. It is useful for various loose-coupling OOP relations
between different entities involving realization, association and
aggregation. In short ... an user can get such interface from some
factory in library and keep it as association with library or has to
implement such interface to inject it into library.

Goran 03-22-2011 02:41 PM

Re: pImpl idiom: Heap vs Stack
 
On Mar 22, 2:37*am, Öö Tiib <oot...@hot.ee> wrote:
> On Mar 21, 3:05*pm, Goran <goran.pu...@gmail.com> wrote:
>
>
>
> > On Mar 21, 11:32*am, Hoyin <haoxian.z...@gmail.com> wrote:

>
> > > I am reading an notes about Pointer To Implementation (pImpl) Idiom
> > > which is trying to decouple the interface and impl via a pointer e.g.

>
> > > class Book
> > > {
> > > public:
> > > * void print(){m_p->print()};
> > > private:
> > > * class BookImpl;
> > > * BookImpl* m_p;

>
> > > };

>
> > > class BookImpl // in a separated file
> > > {
> > > public:
> > > * void print();
> > > private:
> > > * std::string *m_Contents;
> > > * std::string *m_Title;

>
> > > };

>
> > > which avoid re-compile on the client code if we want to add/remove
> > > property for Book (we change class BookImpl's data member rather than
> > > class Book), BUT, in most case, the obj of BookImpl will be allocated
> > > in Heap rather than Stack. Will there be significant cost introduced
> > > by this change (we will be accessing the data from Heap instead of
> > > Stack)? I was told accessing data from Heap is less efficient than
> > > from Stack (even thought we have pointers/address to those memory) but
> > > why? *How we can measures the cost introduced?

>
> > Is there a cost: yes, absolutely.

>
> > Is it significant: bad question. Answer depends very much on how
> > 1. much speed you need
> > 2. what are your call patterns
> > 3. what your implementation (new/delete pair, mostly) and hardware
> > give you,

>
> > How to measure: make two versions (pimpl/"direct") of your code and
> > measure in an __optimized__ (by the compiler) build.

>
> Also things should be measured for real application, not some
> hypothetical "create them a billion" tests.


Well, yes, that's what I meant by "make two versions ... of __your__
code" (emphasis added).

> Pimple's state is cheap to
> swap and to move, (just a single pointer) so for certain algorithms it
> may even result with performance gain.


Well, yes, but a pointer (to the abstract base) is even cheaper to
swap and move. Pimpl doesn't give anything more there.

> > In C++, an abstract base class is a viable alternative to pimpl. Check
> > outhttp://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virtual...

>
> I have to disagree. People use these two things for different goals in
> C++. It is very good that C++ supports such wide variety of idioms so
> good designer can pick exactly fitting tool for each situation. These
> two idioms do not overlap enough to alternate i think.
>
> Pimple is fully implemented class with well-hidden and fire-walled
> inner structure. That makes it useful as (non-abstract) base class or
> as data member ... in OOP terms as generalized parent or as component
> or element. In short ... like a value with functionality. Viable
> alternative is just usual class without such firewall, abstract
> interface does not cut it.
>
> Abstract interface is a set of function descriptions that form an
> interface. It is useful for various loose-coupling OOP relations
> between different entities involving realization, association and
> aggregation. In short ... an user can get such interface from some
> factory in library and keep it as association with library or has to
> implement such interface to inject it into library.


Well... Question was performance-related. If locality of reference
matters on given hardware (which, with virtual base class and virtual
calls, can easily happen), all the better. In light of performance,
conceptual purity matters less, on one hand, and on the other, end
result, functionality-wise, is pretty similar between the two. Hence
"viable alternative".

Goran.


All times are GMT. The time now is 02:52 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.