QTreeWidget speed, was Re: KListBox/KIconView/KListView

Matt Newell newellm at blur.com
Wed Jan 4 21:38:15 GMT 2006


On Wednesday 04 January 2006 15:13, Benjamin Meyer wrote:
> [snip]
>
> > and on that topic, hopefully QTreeWidget will be made to be non-slow in
> > 4.2 too. try adding 100,000 items to a QTreeWidget and watch how adding
> > slows to a crawl =/
>
> For those who haven't seen it, one problem I saw was that as you added one
> row at a time (vs one big block insertRows(0,10000) ) it was taking longer
> and longer, adding 100 rows to 100 was taking 200ms, 100 to 10,000 was
> taking 8000ms. etc"  Adding 10,000 rows could take a number of seconds. 
> Not good
>
> But do not fear!  I have profiled and improved (dramatically in some
> places) a number of spots in itemviews, in particular when data changes and
> when new items are added to tree view and tree widget.
>
> Adding 100 rows now takes about 5ms be it to 100 or 100,000 :)  The fixes
> will be in 4.1.1.
>
> Course when you have 100,000 items you probably want to have your own
> model. Models are cool*.
>
> -Benjamin Meyer
>
> *delegates are there own class of cool because they facilitate eye-candy.


This sounds good, but another speed problem on linux is text painting, it can 
cause large treeview widget with many columns to take a lot of time to paint.  
This patch speeds up text painting quite a bit for me, not sure if it is 
correct.  It causes XRenderCompositeText32 to be called per line instead of 
per glyph.  This should really be looked into, because it really causes most 
of the drawing slowness for my apps.

--- /mnt/storage/qt4snap/src/gui/painting/qpaintengine_x11.cpp  2005-12-20 
16:39:59.000000000 -0800
+++ /mnt/storage/qt41rc1/src/gui/painting/qpaintengine_x11.cpp  2005-12-12 
12:24:13.000000000 -0800
@@ -2103,26 +2101,42 @@
         GlyphSet glyphSet = ft->glyphSet;
         const QColor &pen = d->cpen.color();
         ::Picture src = X11->getSolidFill(d->scrn, pen);
        XRenderPictFormat *maskFormat = 
XRenderFindStandardFormat(X11->display, ft->xglyph_format);

-        QVarLengthArray<XGlyphElt32, 256> glyphSpec(glyphs.size());
-        for (int i = 0; i < glyphs.size(); ++i) {
-            int xp = qRound(positions[i].x);
-            int yp = qRound(positions[i].y);
-            if (xp > SHRT_MIN && xp < SHRT_MAX) {
-                glyphSpec[nGlyphs].glyphset = glyphSet;
-                glyphSpec[nGlyphs].chars = &glyphs[i];
-                glyphSpec[nGlyphs].nchars = 1;
-                glyphSpec[nGlyphs].xOff = xp;
-                glyphSpec[nGlyphs].yOff = yp;
-                ++nGlyphs;
-            }
+               int neededElts = 1;
+               int y = qRound(positions[0].y);
+               for( int i = 1; i < glyphs.size(); i++ ) {
+                       int yp = qRound(positions[i].y);
+                       if( y != yp ) {
+                               y = yp;
+                               neededElts++;
+                       }
+               }
+
+        QVector<XGlyphElt32> glyphSpec(neededElts);
+               int n = 0;
+        for (int i = 0; (i < neededElts) && (n < glyphs.size()); ++i) {
+                       int ys = qRound(positions[n].y);
+            int xp = qRound(positions[n].x);
+                       if (xp > SHRT_MIN && xp < SHRT_MAX) {
+                               glyphSpec[i].glyphset = glyphSet;
+                               glyphSpec[i].chars = &glyphs[n];
+                               glyphSpec[i].nchars = 0;
+                               glyphSpec[i].xOff = xp;
+                               glyphSpec[i].yOff = ys;
+                               while( ys == qRound(positions[n].y) ) {
+                                       glyphSpec[i].nchars++;
+                                       n++;
+                                       if( n >= glyphs.size() )
+                                               break;
+                               }
+                       }
         }

         int i = 0;
-        while (i < nGlyphs) {
+        while (i < neededElts) {
             XRenderCompositeText32 (X11->display, PictOpOver, src, 
d->picture,
                                    maskFormat, 0, 0, 0, 0,
                                     glyphSpec.data() + i, 1);
             ++i;
         }




More information about the kde-core-devel mailing list