Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QAbstractItemModel: much time lost on nothing between beginResetModel() and endResetModel()

QAbstractItemModel: much time lost on nothing between beginResetModel() and endResetModel()

Scheduled Pinned Locked Moved Solved General and Desktop
qabstractitemmotablesspeed
10 Posts 3 Posters 2.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Joachim W
    wrote on 4 Dec 2019, 13:05 last edited by
    #1

    MyTableModel inherits from QAbstractItemModel.

    Occasionally, my data change deeply: new number of rows, and new contents in each single row. So I call from within MyTableModel:

    beginResetModel();
    endResetModel();
    

    This redraws the entire table, calling numerous times the function MyTableModel::data (which overrides QAbstractItemModel::data). Works perfectly, but too slowly. For a table with a few thousand entries, it takes several seconds from beginResetModel to endResetModel.

    Of course my first suspicion was that computations in my own data function take too long. So I replaced it by

    QVariant
    MyTableModel::data(const QModelIndex& index, int role) const override
    {
        return {};
    }
    

    Almost no effect. The seconds are really spent on some Qt internal overhead.

    Questions, obviously: What is Qt doing? How to make it faster?

    J 1 Reply Last reply 4 Dec 2019, 13:11
    0
    • J Joachim W
      4 Dec 2019, 13:05

      MyTableModel inherits from QAbstractItemModel.

      Occasionally, my data change deeply: new number of rows, and new contents in each single row. So I call from within MyTableModel:

      beginResetModel();
      endResetModel();
      

      This redraws the entire table, calling numerous times the function MyTableModel::data (which overrides QAbstractItemModel::data). Works perfectly, but too slowly. For a table with a few thousand entries, it takes several seconds from beginResetModel to endResetModel.

      Of course my first suspicion was that computations in my own data function take too long. So I replaced it by

      QVariant
      MyTableModel::data(const QModelIndex& index, int role) const override
      {
          return {};
      }
      

      Almost no effect. The seconds are really spent on some Qt internal overhead.

      Questions, obviously: What is Qt doing? How to make it faster?

      J Offline
      J Offline
      JonB
      wrote on 4 Dec 2019, 13:11 last edited by
      #2

      @Joachim-W
      begin/endResetModel() tell any attached views that the model has changed, and they need to redraw. They are the callers of the data() method.

      You need to look at whatever views you have attached to the model are up to for the time taken. I don't know how long it takes your view(s) to redraw against "a table with a few thousand entries".

      J 1 Reply Last reply 4 Dec 2019, 13:32
      0
      • J JonB
        4 Dec 2019, 13:11

        @Joachim-W
        begin/endResetModel() tell any attached views that the model has changed, and they need to redraw. They are the callers of the data() method.

        You need to look at whatever views you have attached to the model are up to for the time taken. I don't know how long it takes your view(s) to redraw against "a table with a few thousand entries".

        J Offline
        J Offline
        Joachim W
        wrote on 4 Dec 2019, 13:32 last edited by
        #3

        @JonB MyTableView inherits from QTreeView (and not from QTableView, which for forgotten reasons did not yield the right layout). Upon signal QAbstractItemModel::modelReset, it calls QTreeView::resizeColumnToContents for each column. This is probably a stupid thing to do as it calls MyTableModel::data for all columns and all rows. Yet I wonder: why does this overhead machinery by itself consume much more time than whatever computations within MyTableModel::data?

        J 1 Reply Last reply 4 Dec 2019, 14:08
        0
        • J Joachim W
          4 Dec 2019, 13:32

          @JonB MyTableView inherits from QTreeView (and not from QTableView, which for forgotten reasons did not yield the right layout). Upon signal QAbstractItemModel::modelReset, it calls QTreeView::resizeColumnToContents for each column. This is probably a stupid thing to do as it calls MyTableModel::data for all columns and all rows. Yet I wonder: why does this overhead machinery by itself consume much more time than whatever computations within MyTableModel::data?

          J Offline
          J Offline
          JonB
          wrote on 4 Dec 2019, 14:08 last edited by JonB 12 Apr 2019, 14:10
          #4

          @Joachim-W said in QAbstractItemModel: much time lost on nothing between beginResetModel() and endResetModel():

          Yet I wonder: why does this overhead machinery by itself consume much more time than whatever computations within MyTableModel::data?

          ? Because there's a lot more work to for visual computation that there is for mere model access! For example, resizeColumnToContents() is going to have to measure the font width of every string shown to decide how wide it is in order to line up.... That's why it may not be a great idea to show "thousands" of rows (with multiple columns) in a view, but up to you.

          1 Reply Last reply
          2
          • C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 4 Dec 2019, 15:32 last edited by
            #5

            You should not use QHeaderView::ResizeToContents in your views when there is a large amount of data - because it needs, as @JonB already said, to calculate all cell widths.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            2
            • J Offline
              J Offline
              JonB
              wrote on 4 Dec 2019, 16:14 last edited by JonB 12 Apr 2019, 16:15
              #6

              @Christian-Ehrlicher , @Joachim-W
              As an observation.

              resizeColumnToContents() is slow with a large table model. IIRC, in Windows at least when you double-click on a column-width-drag-resizer-line to make it size to widest shown, I think it always calculates only from those rows/columns which are visible in the current pane. If you scroll down you can still meet wider items, and have to double-click again.

              OTOH, I think the Qt resizeColumnToContents() calculates on all rows/columns in the view, regardless of viewport visibility.

              There will be a big speed difference between these two behaviours on large data. Would be nice if the Qt one could do the visible, fast one, maybe you have to override resizeColumnToContents() with your own code to implement?

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 4 Dec 2019, 16:28 last edited by Christian Ehrlicher 12 Apr 2019, 16:29
                #7

                @JonB said in QAbstractItemModel: much time lost on nothing between beginResetModel() and endResetModel():

                all rows/columns in the view, regardless of viewport visibility.

                No :)

                See https://doc.qt.io/qt-5/qheaderview.html#setResizeContentsPrecision
                And if this is not enough you can overwrite QTableView::sizeHintForColumn() iirc.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                J 1 Reply Last reply 4 Dec 2019, 16:39
                2
                • C Christian Ehrlicher
                  4 Dec 2019, 16:28

                  @JonB said in QAbstractItemModel: much time lost on nothing between beginResetModel() and endResetModel():

                  all rows/columns in the view, regardless of viewport visibility.

                  No :)

                  See https://doc.qt.io/qt-5/qheaderview.html#setResizeContentsPrecision
                  And if this is not enough you can overwrite QTableView::sizeHintForColumn() iirc.

                  J Offline
                  J Offline
                  JonB
                  wrote on 4 Dec 2019, 16:39 last edited by JonB 12 Apr 2019, 16:39
                  #8

                  @Christian-Ehrlicher
                  Wow! Yep, good for you & Qt

                  The default value is 1000
                  Special value 0 means that it will look at only the visible area.

                  @Joachim-W
                  Try changing that value from 1,000 to 0 and see how it affects your speed situation?

                  J 1 Reply Last reply 5 Dec 2019, 09:08
                  0
                  • J JonB
                    4 Dec 2019, 16:39

                    @Christian-Ehrlicher
                    Wow! Yep, good for you & Qt

                    The default value is 1000
                    Special value 0 means that it will look at only the visible area.

                    @Joachim-W
                    Try changing that value from 1,000 to 0 and see how it affects your speed situation?

                    J Offline
                    J Offline
                    Joachim W
                    wrote on 5 Dec 2019, 09:08 last edited by
                    #9

                    I removed the call to resizeColumnToContents() for good. Computation is now faster, and independent of table size.

                    C 1 Reply Last reply 5 Dec 2019, 13:57
                    0
                    • J Joachim W
                      5 Dec 2019, 09:08

                      I removed the call to resizeColumnToContents() for good. Computation is now faster, and independent of table size.

                      C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 5 Dec 2019, 13:57 last edited by
                      #10

                      @Joachim-W Then please mark this topic as solved, thx.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      0

                      9/10

                      5 Dec 2019, 09:08

                      • Login

                      • Login or register to search.
                      9 out of 10
                      • First post
                        9/10
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved