Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.5.1, 5.6.0 RC
-
None
-
32+64bit Linux
-
84f61dd2d2b0140814b39a2c5238a6e31c49abd7 (5.7.0), e38a98ad4453974b2848eeed02d81e0c408ce0c6 (5.6.4)
Description
Setup
We are using a rather large Quick TableView (up to 3000 rows and 10-30 columns) on a Linux machine. The model is modified approximately once per second (add / remove or update single rows).
The TableView is populated by a QAbstractTableModel-based model inside a QSortFilterProxyModel (dynamicSortFilter enabled).
Problem
After switching from Qt 5.3.2 to Qt 5.5.x we noticed a considerable slowdown (and high cpu load), particularly during updates (rows added / removed / updated).
Qt 5.6 does not seem to be quicker (maybe slightly better for small models & without updates)
When using the QtCreator QML Profiler, you can see that a large number of bindings / properties are updated when the sorting changes.
After taking a closer look at the Qt-internal TableView qml files, it turned out that the rowIndex property of rowItem components in BasicTableView.qml are updated very often during the sorting process. A number of properties depend on the rowIndex and are updated subsequently - which increases the load.
Why is the TableView updated during the sorting process?
Note: rowIndex update count seems to be the same in Qt 5.3.2 and Qt 5.6. So maybe the slowdown is completely unrelated...
Expected behavior
When the model is updated the rowIndex properties of all rowItem instances are updated exactly once (at most), even if the model itself contains more rows.
Example 1: column sorting (small model)
- model contains 4 rows
- TableView has 4 rowItem instances
- the sorting order is changed
qml: rowIndex of rowItem instance 0 changed from 0 to 3 qml: rowIndex of rowItem instance 1 changed from 1 to 0 qml: rowIndex of rowItem instance 2 changed from 2 to 1 qml: rowIndex of rowItem instance 3 changed from 3 to 2 qml: rowIndex of rowItem instance 2 changed from 1 to 2 qml: rowIndex of rowItem instance 3 changed from 2 to 1 qml: rowIndex of rowItem instance 3 changed from 1 to 2 qml: rowIndex of rowItem instance 2 changed from 2 to 1 qml: rowIndex of rowItem instance 1 changed from 0 to 1 qml: rowIndex of rowItem instance 2 changed from 1 to 2 qml: rowIndex of rowItem instance 3 changed from 2 to 3 qml: rowIndex of rowItem instance 0 changed from 3 to 0
Expected behavior: rowIndex is updated 4 times
Example 2: column sorting (large model)
- model contains 1000 rows
- TableView has 47 rowItem instances
- the sorting order is changed
rowIndex is updated 1200 times
Expected behavior: rowIndex is updated 47 times
Example 3: data update (small model)
- model contains 4 rows
- TableView has 4 rowItem instances
- first model entry is moved to bottom (single dataChanged call for this line)
qml: rowIndex of rowItem instance 0 changed from 0 to 3 qml: rowIndex of rowItem instance 1 changed from 1 to 0 qml: rowIndex of rowItem instance 2 changed from 2 to 1 qml: rowIndex of rowItem instance 3 changed from 3 to 2 qml: rowIndex of rowItem instance 1 changed from 0 to 1 qml: rowIndex of rowItem instance 2 changed from 1 to 0 qml: rowIndex of rowItem instance 1 changed from 1 to 2 qml: rowIndex of rowItem instance 3 changed from 2 to 1 qml: rowIndex of rowItem instance 1 changed from 2 to 3 qml: rowIndex of rowItem instance 0 changed from 3 to 2
Expected behavior: rowIndex is updated 4 times
Example 4: data update (large model)
- model contains 1000 rows
- TableView has 47 rowItem instances
- first model entry is moved to bottom (single dataChanged call for this line)
rowIndex is updated 1094 times
Expected behavior: rowIndex is updated 47 times
tableviewtest example project
I have attached a small project which can reproduce the problem:
- a model with 1 column and 100 rows
- a proxy model which sorts the model items
- a simple qml page with a TableView and a button for triggering single row updates
Note: with 100 rows the problem is not really noticeable, but you can see it with the QML Profiler.