Re: pImpl idiom: Heap vs Stack
On Mar 22, 4:41 pm, Goran <goran.pu...@gmail.com> wrote:
On Mar 22, 2:37 am, =D6=F6 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 th=
an
class Book), BUT, in most case, the obj of BookImpl will be allocat=
ed
in Heap rather than Stack. Will there be significant cost introduce=
d
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).
OK.
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.
Hmm, i thought you were comparing pimpl with direct object above. Via
abstract interface lets at least agree with a "draw". ;-) Pimple is
also pointer unless it has something additional to carried
implementation.
In C++, an abstract base class is a viable alternative to pimpl. Chec=
k
outhttp://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virt=
ual...
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".
Yes, but that is where i disagreed, the difference of these two is
initially not in performance but in behavior, contract,
responsibilities and guarantees. It is not only conceptual purity
(like arrow type on some uml diagram). The usage of what you can or
have to do to one or other as user of it is different. Pointerness of
pimpl is entirely removed from being users concern. It is ready-made.
Use it as a data member and compiler generated assignment and copy
construction work.
Abstract interface on the other hand is usually up to its user to
manage as a pointer and there is usually pile of managerial concerns
where to acquire and how to release and check for nullness. Then the
users often wrap it into smart pointers and both damage performance
and uglify their code.