D pointers

Kuba Ober kuba at mareimbrium.org
Fri Sep 30 19:50:37 BST 2005


On Friday 30 September 2005 11:46, Lubos Lunak wrote:
> On Friday 30 of September 2005 15:57, Koos Vriezen wrote:
> > On Thursday 29 September 2005 13:49 Lars Knoll wrote:
> > > On Thursday 29 September 2005 11:01, Dirk Mueller wrote:
>
> ...
>
> > > * You can move all private methods into the d-pointer. Since private
> > > classes don't get exported you reduce the number of exported symbols
> > > which in turn reduces library size and startup time.
> >
> > Above points do not address the argument IMO. Inline accessors don't need
> > extra include files. Also this has nothing to do with putting private
> > functions in d-pointer. Actually having inline accessors removes a symbol
> > (hidden inlines) and as such speeds up application loading (w/ g++ >
> > 4.0.0)
> >
> > On kdelibs 3.3.2 debian/testing:
> >  nm -C -D /usr/lib/libkdecore.so.4.2.0 |grep " W " |wc -l
> >  1736
> >  nm -C -D /usr/lib/libkdecore.so.4.2.0 |grep " T " |wc -l
> >  4223
> > On kdelibs 3.5 branch compiled w/ visibility:
> >  nm -C -D $KDEDIR/lib/libkdecore.so.4.2.0 |grep " W " |wc -l
> >  137
> >  nm -C -D $KDEDIR/lib/libkdecore.so.4.2.0 |grep " T " |wc -l
> >  4138
> >
> > So putting everyting back to " T " adds here about 1600 symbols only for
> > libkdecore and that will slowdown startup for sure.
>
>  You need to add also grep -v "<.*>" there, to get rid of all the template
> instantiations, which have nothing to do with this. That brings it down to
> about 500. That's quite a lot to be sure, but it's enough for me to bet on
> the fact that all of those are out-of-line copies of virtual inline methods
> and similar cases where gcc can't decide on a single place to put them.
> Which means you haven't measured anything useful, at least not for this
> case.
>
>  Doing grep ").*{" *.h | wc -l in kdecore, which is the best way I can
> think of, says there are about 350 inlines in kdecore. And actually the
> dynamic linker is not that bad these days, from LD_DEBUG=statistics about
> 0,13s (2GHz machine) is spent on that for KWrite. So with 500MHz machine
> turning all those inlines into non-inlines will increase the cost from 0,6s
> to ... uhm ... some maths, guesses and being pessimistic ... 0,8s . Big
> deal.  And this is the guy often working on optimizations saying this.
>
>  My opinion, in short, is. We need d-pointers. Moving all members from the
> class to the private class doesn't cause any important performance impact,
> except (possibly) for heavily used classes. 

For those one can use a specialized allocator to quickly allocate those 
private data structures. There's still one indirection layer, but in many 
cases the compiler should be able to optimize that as there's little 
difference between accessing the data via 'this' pointer vs. via some other 
pointer, namely 'this->d'. To help some more with that (if it helps!), one 
could have the d pointer declared const.

One nice way to implement it is called 'fast pimpl idiom', presented e.g. in 
Item 30 of Herb Sutter's Exceptional C++.

In the nutshell, one has:

struct MyClass::MyClassPrivate : FastObject {
...
};

class FastObject {
public:
	static void * operator new(size_t s) {
		return FixedAllocator::instance()->allocate(s);
	}
	static void operator delete(void* p) {
		FixedAllocator::instance()->deallocate(p);
	}
	// those get inherited by MyClassPrivate
}

class FixedAllocator {
public:
	static FixedAllocator & instance(); // singleton pattern
	void * allocate(size_t);
	void deallocate(void *);
}

The FixedAllocator should implement a fixed size allocation scheme which, 
hopefully, would be more efficient than malloc/free.

Cheers, Kuba Ober




More information about the kde-core-devel mailing list