Results 1 to 8 of 8

Thread: Bad performance of QGraphicsScene

  1. #1
    Join Date
    Aug 2008
    Posts
    70
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Unhappy Bad performance of QGraphicsScene

    Hello,

    I am creating a QGraphicsScene containing only 1416 rects with the following code (see next thread).

    As you can see in traces, I have very bad performances:
    Qt Code:
    1. ## >SKGTableWithGraph::redrawGraph
    2. ## >SKGTableWithGraph::redrawGraph-remove scene
    3. ## <SKGTableWithGraph::redrawGraph-remove scene TIME=0.287117 ms
    4. ## >SKGTableWithGraph::redrawGraph-create scene
    5. ## Scene rect:-10,-354833,394415,394435
    6. ## Items:24x59=1416
    7. ## <SKGTableWithGraph::redrawGraph-create scene TIME=57306.6 ms
    8. ## >SKGTableWithGraph::redrawGraph-add scene to view
    9. ## <SKGTableWithGraph::redrawGraph-add scene to view TIME=1.1489 ms
    10. ## <SKGTableWithGraph::redrawGraph TIME=57312.6 ms
    To copy to clipboard, switch view to plain text mode 

    57s are needed just to build the scene

    In my code, if I comment the addRect methods like this:
    Qt Code:
    1. if (mode==0) {
    2. //STACK
    3. if (val>0) {
    4. //graphItem=scene->addRect(width*x, -yPlus, width, -val, QPen(), QBrush(color));
    5. yPlus+=val;
    6. if (yPlus>ymax) ymax=yPlus;
    7. } else if (val<0) {
    8. //graphItem=scene->addRect(width*x, -yMoins, width, -val, QPen(), QBrush(color));
    9. yMoins+=val;
    10. if (yMoins<ymin) ymin=yMoins;
    11. }
    12. } else if (mode==1) {
    To copy to clipboard, switch view to plain text mode 

    then I have very good performances but my scene is empty (of course).
    Qt Code:
    1. ## >SKGTableWithGraph::redrawGraph
    2. ## >SKGTableWithGraph::redrawGraph-remove scene
    3. ## <SKGTableWithGraph::redrawGraph-remove scene TIME=0.179953 ms
    4. ## >SKGTableWithGraph::redrawGraph-create scene
    5. ## Scene rect:-10,-354833,394415,394435
    6. ## Items:24x59=1416
    7. ## <SKGTableWithGraph::redrawGraph-create scene TIME=9.6991 ms
    8. ## >SKGTableWithGraph::redrawGraph-add scene to view
    9. ## <SKGTableWithGraph::redrawGraph-add scene to view TIME=0.407059 ms
    10. ## <SKGTableWithGraph::redrawGraph TIME=13.9419 ms
    To copy to clipboard, switch view to plain text mode 

    Conclusion: Bad performances are due to addRect method.

    Question: What is the solution to improve performances ?
    I don't understand why "40000 Chips" example is very fast and not my "1416 rects" example !

  2. #2
    Join Date
    Aug 2008
    Posts
    70
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Bad performance of QGraphicsScene

    Qt Code:
    1. void SKGTableWithGraph::redrawGraph()
    2. {
    3. SKGTRACEIN(10, "SKGTableWithGraph::redrawGraph");
    4. QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
    5.  
    6. ui.graphicView->hide();
    7.  
    8. //Recreate scene
    9. if (scene) {
    10. SKGTRACEIN(10, "SKGTableWithGraph::redrawGraph-remove scene");
    11. scene->clear();
    12. delete scene;
    13. }
    14.  
    15.  
    16. scene=new QGraphicsScene();
    17. {
    18. SKGTRACEIN(10, "SKGTableWithGraph::redrawGraph-create scene");
    19. //Get current selection
    20. int crow=ui.kTable->currentRow();
    21. int ccolumn=ui.kTable->currentColumn();
    22.  
    23. int nbRows=ui.kTable->rowCount()-1; //Sum
    24. int nbColumns=ui.kTable->columnCount();
    25. int sumColumnIndex=nbColumns-1;
    26. if (nbColumns>2) {
    27. nbColumns=nbColumns-2; //Sum and average
    28. --sumColumnIndex;
    29. }
    30. KLocale* locale=KGlobal::locale();
    31.  
    32. int mode=ui.kDisplayMode->currentIndex();
    33.  
    34. //Compute y limits
    35. double minLimit=0;
    36. double maxLimit=0;
    37. if (mode==0) {
    38. //STACK
    39. for (int x=0; x<nbRows; ++x) {
    40. QTableWidgetItem* tableItem=ui.kTable->item(x,sumColumnIndex);
    41. if (tableItem) {
    42. QString valstring=tableItem->text();
    43. double val=locale->readMoney(valstring);
    44. minLimit=qMin(minLimit, val);
    45. maxLimit=qMax(maxLimit, val);
    46. }
    47. }
    48. } else if (mode==1) {
    49. //HISTOGRAM
    50. for (int x=0; x<nbRows; ++x) {
    51. for (int y=0; y<nbColumns; ++y) {
    52. QTableWidgetItem* tableItem=ui.kTable->item(x,y);
    53. if (tableItem) {
    54. QString valstring=tableItem->text();
    55. double val=locale->readMoney(valstring);
    56. minLimit=qMin(minLimit, val);
    57. maxLimit=qMax(maxLimit, val);
    58. }
    59. }
    60. }
    61. }
    62.  
    63. //Compute
    64. double width=10;
    65. double margin=width;
    66. double maxX=0;
    67. if (nbRows) {
    68. if (mode==0) {
    69. width=(maxLimit-minLimit)/nbRows;
    70. maxX=width*nbRows+margin;
    71. } else if (mode==1) {
    72. width=(maxLimit-minLimit)/(nbRows*nbColumns);
    73. maxX=width*(nbColumns-1)*nbRows+margin;
    74. }
    75. }
    76. scene->setSceneRect(-margin, margin-maxLimit, maxX-margin, maxLimit-minLimit+2*margin);
    77. scene->setItemIndexMethod(QGraphicsScene::NoIndex);
    78.  
    79. SKGTRACE << "Scene rect:" <<scene->sceneRect().x() << "," << scene->sceneRect().y()<< "," << scene->sceneRect().width()<< "," << scene->sceneRect().height() << endl;
    80. SKGTRACE << "Items:" <<nbRows << "x" << (nbColumns-1) << "=" << nbRows*(nbColumns-1) << endl;
    81.  
    82. //Redraw scene
    83. double ymin=0;
    84. double ymax=0;
    85. double histoPos=0;
    86. for (int x=0; x<nbRows; ++x) {
    87. QString xname=ui.kTable->item(x, 0)->text();
    88. double yPlus=0;
    89. double yMoins=0;
    90. for (int j=1; j<nbColumns; ++j) {
    91. //Get column name
    92. QString yname=ui.kTable->horizontalHeaderItem(j)->text();
    93.  
    94. //Get cell value
    95. QTableWidgetItem* tableItem=ui.kTable->item(x,j);
    96. if (tableItem) {
    97. QString valstring=tableItem->text();
    98. double val=locale->readMoney(valstring);
    99.  
    100. int color_h=359*x/nbRows;
    101. int color_s=255-155*j/nbColumns;
    102. int color_v=255-155*j/nbColumns;
    103.  
    104. QColor color;
    105. if (x==crow && j==ccolumn) color=QApplication::palette().color(QPalette::Highlight);
    106. else color=QColor::fromHsv(color_h,color_s,color_v);
    107.  
    108. QAbstractGraphicsShapeItem* graphItem=NULL;
    109. if (mode==0) {
    110. //STACK
    111. if (val>0) {
    112. graphItem=scene->addRect(width*x, -yPlus, width, -val, QPen(), QBrush(color));
    113. yPlus+=val;
    114. if (yPlus>ymax) ymax=yPlus;
    115. } else if (val<0) {
    116. graphItem=scene->addRect(width*x, -yMoins, width, -val, QPen(), QBrush(color));
    117. yMoins+=val;
    118. if (yMoins<ymin) ymin=yMoins;
    119. }
    120. } else if (mode==1) {
    121. //HISTOGRAM
    122. graphItem=scene->addRect(width*histoPos, 0, width, -val, QPen(), QBrush(color));
    123. histoPos++;
    124. if (val>ymax) ymax=val;
    125. if (val<ymin) ymin=val;
    126. }
    127.  
    128. if (graphItem) {
    129. graphItem->setToolTip(xname+'\n'+yname+'\n'+valstring+'\n'+tableItem->toolTip());
    130. graphItem->setFlags(QGraphicsItem::ItemIsSelectable);
    131. graphItem->setData(1, x);
    132. graphItem->setData(2, j);
    133. graphItem->setData(11, color_h);
    134. graphItem->setData(12, color_s);
    135. graphItem->setData(13, color_v);
    136.  
    137. tableItem->setData(1, (qlonglong) graphItem);
    138. }
    139. }
    140. }
    141. }
    142.  
    143. //Draw axis
    144. if (mode!=2) {
    145. QGraphicsLineItem* item=scene->addLine(0, -ymin+margin, 0, -ymax-margin);
    146. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    147.  
    148. item=scene->addLine(0, -ymax-margin, margin/2, -ymax-margin/2);
    149. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    150.  
    151. item=scene->addLine(0, -ymax-margin, -margin/2, -ymax-margin/2);
    152. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    153.  
    154. item=scene->addLine(-margin, 0, maxX, 0);
    155. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    156.  
    157. item=scene->addLine(maxX, 0, maxX-margin/2, margin/2);
    158. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    159.  
    160. item=scene->addLine(maxX, 0, maxX-margin/2, -margin/2);
    161. item->setFlag(QGraphicsItem::ItemIsSelectable, false);
    162. }
    163. }
    164. {
    165. SKGTRACEIN(10, "SKGTableWithGraph::redrawGraph-add scene to view");
    166. ui.graphicView->setScene(scene);
    167. ui.graphicView->onZoomOriginal();
    168. ui.graphicView->show();
    169. ui.graphicView->graphicsView()->setOptimizationFlag(QGraphicsView::DontClipPainter, true);
    170. ui.graphicView->graphicsView()->setOptimizationFlag(QGraphicsView::DontSavePainterState, true);
    171. ui.graphicView->graphicsView()->setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, true);
    172.  
    173. //Add selection event on scene
    174. connect(scene, SIGNAL(selectionChanged()), this, SLOT(onSelectionChangedInGraph()), Qt::QueuedConnection);
    175. }
    176. QApplication::restoreOverrideCursor();
    177. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Bad performance of QGraphicsScene

    First of all add all items to the scene before setting it on the view. Otherwise you get a refresh of the view every time you add an item to the scene.

    Second of all I don't what what your redrawGraph method does, but it recreates all the items instead of using the ones that are already there. Consider a situation where you are building a castle using some building blocks like LEGO. With your current approach if you want to add a new block to the construction, you first dismantle all that you have already constructed, then construct it back and add that new block. Not very efficient, is it? Maybe it's better to simply add that block to the ones that are already there?

  4. #4
    Join Date
    Aug 2008
    Posts
    70
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Bad performance of QGraphicsScene

    Hi Wysota,

    First of all add all items to the scene before setting it on the view. Otherwise you get a refresh of the view every time you add an item to the scene.
    It's already the case. The scene is created and added to the view.

    Second of all I don't what what your redrawGraph method does, but it recreates all the items instead of using the ones that are already there. Consider a situation where you are building a castle using some building blocks like LEGO. With your current approach if you want to add a new block to the construction, you first dismantle all that you have already constructed, then construct it back and add that new block. Not very efficient, is it? Maybe it's better to simply add that block to the ones that are already there?
    This method creates the view representing the content of a QTableWidget. This method is called when the QTableWidget is populated. So the graph is never updated or modified.

    My problem is that the initial creation is very long.
    I don't understand why "40000 chips" example is able to create 40000 object in less than 1s and why I need 57s to create 1416 rects only.

    What is wrong ?

    PS: Sorry for the previous long message.
    Last edited by jacek; 21st November 2008 at 23:11. Reason: changed [code] to [quote]

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Bad performance of QGraphicsScene

    I'd suggest running this code via callgrind to see where the most time is spent. I wouldn't be surprised if it was in the table widget.

    Why is your method called "redraw" if it doesn't redraw?

  6. #6
    Join Date
    Aug 2008
    Posts
    70
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Bad performance of QGraphicsScene

    Wysota,

    Performances are very good (13.9419 ms) when the following line is commented:
    Qt Code:
    1. graphItem=scene->addRect(width*x, -yMoins, width, -val, QPen(), QBrush(color));
    To copy to clipboard, switch view to plain text mode 

    and very bad (57312.6 ms) when this line is not commented.

    There are nothing concerning QTableView in this line.
    I will try callgrind...

    Thank you for your help.

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Bad performance of QGraphicsScene

    Is there a chance you could provide a minimal compilable example reproducing the problem?

  8. #8
    Join Date
    Aug 2008
    Posts
    70
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default [RESOLVED] Bad performance of QGraphicsScene

    Hi Wisota,

    I found my error, in fact bad performance was due to the following line:
    Qt Code:
    1. tableItem->setData(1, (qlonglong) graphItem);
    To copy to clipboard, switch view to plain text mode 

    So, you are right, it's due to the QTableView ! Good job !

    I found a solution:
    1-call QTableView::hide at the beginning of SKGTableWithGraph::redrawGraph
    2-call QTableView::shod at the end of SKGTableWithGraph::redrawGraph

    I have now good performances:
    Qt Code:
    1. ## >SKGTableWithGraph::redrawGraph
    2. ## >SKGTableWithGraph::redrawGraph-remove scene
    3. ## <SKGTableWithGraph::redrawGraph-remove scene TIME=0.206 ms
    4. ## >SKGTableWithGraph::redrawGraph-create scene
    5. ## Scene rect:-10,-350985,390567,390587
    6. ## Items:24x59=1416
    7. ## <SKGTableWithGraph::redrawGraph-create scene TIME=90.5479 ms
    8. ## >SKGTableWithGraph::redrawGraph-add scene to view
    9. ## <SKGTableWithGraph::redrawGraph-add scene to view TIME=454.512 ms
    10. ## <SKGTableWithGraph::redrawGraph TIME=551.457 ms
    To copy to clipboard, switch view to plain text mode 

    Thank you again for your help.

Similar Threads

  1. Replies: 12
    Last Post: 7th September 2011, 16:37
  2. QGraphicsScene performance
    By Aceman2000 in forum Qt Programming
    Replies: 4
    Last Post: 2nd June 2008, 18:10
  3. GraphicsView performance problems
    By Gopala Krishna in forum Qt Programming
    Replies: 79
    Last Post: 8th August 2007, 17:32
  4. When to use QGraphicsScene or QWidget
    By fossill in forum Qt Programming
    Replies: 2
    Last Post: 9th February 2007, 23:58

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.