QSortFilterProxyModel is slow to sort periodically
-
I have a large model that I wrapped with a custom
QSortFilterProxyModel
The view that the proxy model is set to is sorted by a column. Every 1 second, I update the model and proxy model has to rearrange the rows so that the sort order is intact. However, this seems to be slowing down UI. Probably, there are many rows that needs rearrangement. Is there are a way to handle this, or should I give up on sorting by a column? -
I actually have around 100'000-120'000 rows at most. But users of the application filter most of the rows out, they usually have 100-2000 rows present on the screen most of the time. I actually did not use
dynamicSortFilter()
, should I use it? I see that this istrue
by default, I did not disable it. I did not measure how much time it takes, I do not know how to measure it. However, there is a noticable slowdown on UI when sorting takes place, and that is more than enough for me to not like it. When I do the sorting by a static field, there is no slowdown (or no noticeable slowdown I should say) on my machine.I realized that my question was not clear enough. When I do the sorting by a column that has a dynamic value, the sorting is slow. When I do the sorting by a column that has a static value, performance seems to be OK. I can verify this observation by watching CPU utilization values from
top
command. Fast case seems to be using much much less CPU compared to the slow case. -
@ozcanay said in QSortFilterProxyModel is slow to sort periodically:
I actually have around 100'000-120'000 rows at most.
That's still a fair amount to sort.
But users of the application filter most of the rows out, they usually have 100-2000 rows present on the screen most of the time
Was that indeed
2000
or did you intend200
?I don't know, but I think it might sort before filtering, so has to work on the whole 100--200K rows.
I actually did not use dynamicSortFilter(), should I use it? I see that this is true by default
slowdown on UI when sorting takes placeWith
dynamicSortFilter
on I am unsure whether complete re-sort ever has to take place. So you force a re-sort? You could always try switching it off versus on to see if any difference.When I do the sorting by a column that has a dynamic value, the sorting is slow. When I do the sorting by a column that has a static value, performance seems to be OK
This may be the crux of the issue, but what does it mean? How does a column have a "static" value? Every row has the same value in the column, and so sorting is pointless?? What does a "dynamic" value mean? Do you calculate the values you sort on? Do you have your own
lessThan()
method defined? -
@JonB
Okay, I will be more precise: I am storingOrder
objects in the model. 2 of the members of this object islast_update_time
andcreate_time
.last_update_time
is updated frequently when an order is replaced or executed, howevercreate_time
is a static field (it never changes). Sorting bylast_update_time
seems to be way slower compared to sorting bycreate_time
.I do not have
lessThan()
defined in the proxy model.I enforce sorting in widget object:
orders_proxy_model_->sort(SORT_COLUMN, Qt::DescendingOrder);
I use proxy model just for filtering purposes. Maybe, I should do the sorting there as well.
-
@ozcanay said in QSortFilterProxyModel is slow to sort periodically:
I use proxy model just for filtering purposes. Maybe, I should do the sorting there as well.
Well, you just showed that you call
orders_proxy_model_->sort()
, so it seems to me you do do sorting in the proxy model? I'm a bit lost, make sure it only sorts/reorders the proxy model, not the source model?I don't know why it's faster sorting by
create_time
compared tolast_update_time
, assuming these are bothQDateTime
s it's the same comparison. Maybe because the order does not change with the former there is some optimization because it was already sorted and the new sort order is no different?If you have
dynamicSortFilter
enabled I don't think you should need to callsort()
. I believe when you alter a row in the source model the infrastructure just moves that row's order in the proxy without re-sorting the whole 100K rows, wheresort()
does do the whole 100K rows, and perhaps causes a complete redraw where not necessary. You will have to play. I think you will want eitherdynamicSortFilter = true
or do your own calls tosort()
whenever, not both?You should time your call to
orders_proxy_model_->sort(SORT_COLUMN, Qt::DescendingOrder);
. How long does that take on its own? Is that "slow", or is it perhaps the update/refresh to whatever attached view to redraw itself which is "slow"? -
When you use QDateTime from QFileInfo you should take a look at https://bugreports.qt.io/browse/QTBUG-100349 and the corresponding discussion here: https://forum.qt.io/topic/133954
-
@ozcanay
@Christian-Ehrlicher has an amazing memory! You definitely should look at what he is referring to, the bug report statesQFileInfo::fileTime() seems to be very slow. This is esp. noticeable when someone tries to sort for e.g. modification time.
which seems to be just what you are reporting!