Results 1 to 8 of 8

Thread: QTableView performance

  1. #1
    Join Date
    Jun 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QTableView performance

    Hi, we are trying to implement some kind of real-time data monitor. The bundle of data arrives (in separate thread) about 10 times per second. It contains table of 10x5 cells. When we display it in TableView overall performance too slow. Application's CPU usage is about 80% for 10 of such tables. Analysis shows that there are about 1000 calls per sec from View to Model::data() for each Model. We need a fast way to show table of homogeneous data without such overhead. Does Qt provide solution for such requirements?

    PS. Sorry for my English

  2. #2
    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: QTableView performance

    Don't add rows to the model one by one but do it in batches (i.e. once a second) using a dedicated method. Performance should improve drastically.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jun 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTableView performance

    Our models have fixed size - it's the size of incoming data. So we don't add rows to the model at all - we replace whole table as often as data arrive. We return item's representaion from model's data() method and see there significant overhead.

    If Qt provides more specific solution for our condition It can help a lot.
    Last edited by Anchor; 1st June 2009 at 11:45.

  4. #4
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTableView performance

    can you show us the code? especially the part which is doing model update
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  5. #5
    Join Date
    Jun 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTableView performance

    We don't use QAbstractTableModel's rows and columns. Instead of this we use own containers and bind View with the dataChanged signal.
    Qt Code:
    1. void GlassView::setModel(QAbstractItemModel* model)
    2. {
    3. if (model) {
    4. QTableView::setModel(model);
    5. //connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SIGNAL(sizeChanged()));
    6. connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(updatePropertiesForSaving()));
    7. connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(updateTitle()));
    8. connect(model, SIGNAL(resetSelectDataSet()), SLOT(onSelectDataSetReset()));
    9. connect(model, SIGNAL(resetGlassDataSet()), SLOT(onGlassDataSetReset()));
    10.  
    11. showEarnColumns(isEarnColumnsShown_);
    12. updatePropertiesForSaving();
    13. resizeColumnsToContents();
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 
    As soon as data has been received we notify View by
    Qt Code:
    1. emit dataChanged();
    To copy to clipboard, switch view to plain text mode 

    Model's data method provides access to data
    Qt Code:
    1. QVariant GlassModel::data( const QModelIndex &index, int role ) const
    2. {
    3.  
    4. int currentDepth = ((userDepth_ > 0) && (userDepth_ < maximumDepth_) ? userDepth_ : maximumDepth_);
    5. int offset = currentDepth - ((sortOrder_ == SortOrder::Ascending) ? agregatedAskQuantity_.count() : agregatedBidQuantity_.count());
    6. offset = ((offset < 0 || !showEmptyLines_) ? 0 : offset);
    7.  
    8. int currentRow = index.row();
    9. int currentColumn = index.column();
    10.  
    11. switch(role) {
    12. case Qt::UserRole: { // data needed for emiting; not rounded prices only
    13. if (currentColumn == 2 && (currentRow >= offset && currentRow < (keys_.count() + offset)))
    14. return keys_[currentRow - offset];
    15. if (index.row() < dataTableForDisplay_.count() && index.column() < dataTableForDisplay_[index.row()].count())
    16. return dataTableForDisplay_[index.row()][index.column()];
    17. return emptyVariant_;
    18. }
    19.  
    20. case Qt::DisplayRole: {
    21. // Draw last line (row)
    22. if (index.row()+1 == rowCount_) {
    23. switch(index.column()) {
    24. case 1: {
    25. QVariant total = (columnOrder_ == ColumnOrder::BuyPriceSell ? buyTotal_ : sellTotal_);
    26. return QString("%L1").arg(total.toDouble(), 0, 'f', 0);
    27. }
    28. case 2:
    29. return QString(tr("Р'С_РчР_Р_"));
    30. case 3: {
    31. QVariant total = (columnOrder_ == ColumnOrder::BuyPriceSell ? sellTotal_ : buyTotal_);
    32. return QString("%L1").arg(total.toDouble(), 0, 'f', 0);
    33. }
    34. default:
    35. return emptyVariant_;
    36. }
    37. }
    38. // Draw data
    39. return dataTableForDisplay_[index.row()][index.column()];
    40. }; break;
    41. case Qt::ToolTipRole:
    42. return emptyVariant_;
    43. case Qt::TextAlignmentRole:
    44. if (index.row()+1 == rowCount_ && index.column() == 2)
    45. return QVariant(Qt::AlignHCenter|Qt::AlignVCenter); // for
    46. return QVariant(Qt::AlignRight|Qt::AlignVCenter);
    47.  
    48. case Qt::FontRole: {
    49. if((index.row() + 1) == rowCount_ && (index.column() == 1 || index.column() == 3)){
    50. return variantBoldFont_;
    51. }
    52. return emptyVariant_;
    53. }
    54.  
    55. case Qt::BackgroundRole: //Qt::BackgroundColorRole
    56. if (index.row() % 2)
    57. return QBrush(modelSettings_.evenRowColor);
    58. return QBrush(modelSettings_.oddRowColor);
    59.  
    60. case Qt::ForegroundRole: {//Qt::TextColorRole
    61. // if (currentRow >= offset && currentRow < (keys_.count() + offset)) {
    62. // Price price = keys_[currentRow - offset];
    63. // if (orderPricesBuy_.contains(price) || orderPricesSell_.contains(price))
    64. // return QBrush(QColor(250, 20, 20)); // indicate our bid
    65. // }
    66. return QBrush(modelSettings_.normalTextColor);
    67. }
    68. case Qt::WhatsThisRole:
    69. return emptyVariant_;
    70.  
    71. default:
    72. return emptyVariant_;
    73. }
    74. }
    To copy to clipboard, switch view to plain text mode 

    dataTableForDisplay_ already contains prepared for displaying data.

    So we are looking for any significant performance related improvents of this code. Let me know if such approach isn't applicable for fast data displaying and point me to the right direction if it's possible. Thank you.

    PS
    Sorry for my English

  6. #6
    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: QTableView performance

    Quote Originally Posted by Anchor View Post
    Our models have fixed size - it's the size of incoming data. So we don't add rows to the model at all - we replace whole table as often as data arrive. We return item's representaion from model's data() method and see there significant overhead.
    My hint still applies. The point is not to emit a signal for every cell but for a group of cells. Provide a custom method which will do the changes in batches and emit the dataChanged() signal once, not many times.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jun 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTableView performance

    My hint still applies. The point is not to emit a signal for every cell but for a group of cells. Provide a custom method which will do the changes in batches and emit the dataChanged() signal once, not many times.
    So... we do exactly the same thing. We prepare all data (5x10 cells) and emit dataChanged() signal once (it occures about 10 times per second). But we see that View (after receiving this signal) enumerates cell's to get data. And View do it (enumerating) many times (up to 4 times only for DisplayRole) to get metrics and so on.

  8. #8
    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: QTableView performance

    That you can't avoid, this is the nature of ItemViews. Is your data() implementation so expensive? Could you maybe cache data?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Performance with QTableView and QAbstractTableModel
    By MBex in forum Qt Programming
    Replies: 3
    Last Post: 25th February 2009, 08:04
  2. Replies: 1
    Last Post: 23rd December 2008, 15:42
  3. QTableView Performance Problem on Windows
    By umitoz in forum Qt Programming
    Replies: 1
    Last Post: 31st August 2007, 16:47
  4. Replies: 9
    Last Post: 23rd November 2006, 11:39
  5. Multi-line messages in QTableView
    By Conel in forum Qt Programming
    Replies: 6
    Last Post: 13th April 2006, 13:49

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.