More KRatingPainter optimizations

Following the optimization I made last night to KRatingPainter’s paint function, (KRatingPainter is what paints those nice little rating stars in Dolphin, Gwenview, and some Muon-related project that I’m not quite ready to receive UI criticism for :P) I discovered that there were also a suspicious amount of KColorScheme-related calls coming from somewhere. Since KCacheGrind is such a lovely tool, I was able to deduce quickly that these were coming from the KIconEffect::apply() calls that KRatingPainter::paint() was calling.

There are several ways to call KIconEffect::apply(). (See They all differ in what parameters you supply to the function. Some are more efficient than others. In our case, KRatingPainter was using the following apply() function:

QPixmap  apply (const QImage &src, int effect, float value, const QColor &rgb, bool trans) const

This function takes your picture, the effect you want the strength of your effect, a color to use should the effect support a separate color, and a boolean value to determine whether or not to apply transparency. This is actually a convenience function, since icon effects that require colors require two different colors in some cases. In these cases KIconEffect uses KColorScheme to determine what the best color to use in these cases would be.

The effect in use by KRatingPainter, the “to gray” effect, does not require any additional colors to be specified at all, so by using the wrong apply() function KRatingPainter was spending time finding a color that would never be used. I remedied this by using this overload of the apply() function:

QPixmap apply (const QPixmap &src, int effect, float value, const QColor &rgb, const QColor &rgb2, bool trans) const

This one makes you specify two colors, so time is not wasted looking in your color scheme configuration to determine the best color. I just specified two colorless colors (null QColor()’s, to be technical) and everything was fine and dandy from there on out. It sped up KRatingPainter at least another 10x, on top of the 500x gained from last night’s optimization. In my delegate’s case, this optimization cut the time my ItemView delegate spent painting in half. (A bit more, actually, though data for my delegate specifically is not included in the below screenshot.)

I am fairly sure that rating painting is no longer a bottleneck in my ModelView Delegate class anymore. Compared to last night, I can make it much bigger before seeing noticeable losses of scrolling fluidity.  It should be really fast now, and other applications should be able to benefit from these changes in KDE 4.6 as well.

So, in conclusion, valgrind/callgrind and KCacheGrind (valgrind/callgrind file viewer) are invaluable tools, and are a must-have for any KDE developer. This is by no means the first time that they’ve helped me discover bottlenecks, but this is one of the more drastic optimizations that they have helped me find.


12 Responses to More KRatingPainter optimizations

  1. Maik says:

    This is a classic of the IMO performance killer #1: search

    Thanks for documenting your journey.

    But do you realize that the two screenshots are absolutely identlical??

  2. TooTea says:

    There’s some confusion regarding those prototypes: The first one possibly doesn’t return QPixmap and the second one should is missing the const QColor &rgb2

  3. Federico says:

    Beautiful work, thanks for spending time on optimization… the devil is in the details…

    Bleeding edge AND optimized! What else can we ask for?

  4. Click says:

    Any hints when these optimizations will be included in the kdelibs? 🙂

  5. Alexander Neundorf says:

    Great work 🙂

    I think it would be also a good idea to add some notes about the performance characteristics to the KIconEffect documentation, so that other users of this class can avoid these mistakes you found.


  6. Andrew M says:

    Awesome work. I am sure the rest of the KDE community appreciates this as much as I do. Thank you for your hard work in optimizations.

  7. […] triggered by Jonathan’s blog post (and the followup) on speeding up KRatingPointer via finding bottlenecks through callgrind I did the same again for […]

  8. […] regular readers of my blog, the Muon Software Center is what prompted me to do my KRatingPainter optimizations. Scrolling the applications list was seriously slow before them. It’s nice and smooth now, […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: