From kde-core-devel Thu Sep 29 11:49:08 2005 From: Lars Knoll Date: Thu, 29 Sep 2005 11:49:08 +0000 To: kde-core-devel Subject: Re: D pointers Message-Id: <200509291349.09929.lars () trolltech ! com> X-MARC-Message: https://marc.info/?l=kde-core-devel&m=112799458730617 On Thursday 29 September 2005 11:01, Dirk Mueller wrote: > On Thursday 29 September 2005 10:06, Zack Rusin wrote: > > the other way around. Lars can tell you more about his futile attempts > > of optimizing this class (making it use lazy-parsing). Everything is > > inlined so we couldn't do anything. > > So the issue wasn't the missing d pointer. Yes, the d pointer would have > enforced to not write inline accessors, but other than that, inlined > accessors are still faster than non-inlined ones. And except for very few cases it doesn't matter that your access is not inlined. A typical GUI application is idle 99% of it's time. Things that have to be fast are mostly startup, painting and processing of large amounts of data. Inline methods in an API severly limit the possibilities you later on have to change/refactor (and thus improve) your implementation. We (as in the developers at Trolltech) have been bitten by this quite a few times during the lifetime of Qt3. This is one of the reasons we changed our policy for Qt4. We moved everything into the d pointer for lots of reasons: * We allocate a d pointer anyway. Even if you could avoid it in a 4.0 release by moving all members into the class itself you will most probably need the d pointer in a 4.1/4.2 release. * You keep the public API clean and uncluttered. The header files remain very readable. * You don't need to include thousands of header files; forward declarations are usually enough. This also reduces dependencies and compile time. * Sometimes you use some variables in your class and you would like to replace them by something else in the next revision. You can only do that freely if the member is inside the d pointer. * 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. > > QUrl does create a Private and is > > probably around 10x faster > > For different reasons. For example it doesn't do all those strange url > reencodings KURL does. The main problem was the KURL provided inline accessors to more or less all it's data. I wanted to make it faster at some point because the algorithm for visited links in KHTML used them (and was terribly slow). I had quite a few ideas how one could have done it, but none of them was possible _because_ all the accessors where inline. So I ended up using strings instead of KUrls in khtml for the task at hand. If we stay with KURL as an example, what does it help you to have inline accessors for all data members, if construction of the object takes ages (and you can't fix it later). The positive effect of having these inline members was completely destroyed by the fact that we couldn't refactor the implementation to make it fast. The main issue is usually that inlining looks like it makes things fast, but without measuring you do not know where your bottlenecks are. In most cases they are not the accessors for simple properties. But inlining might prevent future optimisations of your class. So in general I think one should not inline unless there is a _very_ good reason to do so. Having method inline makes sense in one case: When you have a lowlevel class that you need to use in tight inner loops where you process lots of data. Basically container classes as QString, QList etc. But then you have to invest lots of resources to make sure you can live with the implementation for the lifetime of KDE4. But even then you usually put the data into a d-pointer to be able to use implicit sharing. The good old rule that you shouldn't optimise without having measured also applies here. The gained flexibility by having the data structures hidden usually more than outweighs a loss of speed that is in most cases not even measurable. Lars