perf(SortFilterProxyModel): Improve sorting performance
Implement strict less in lessThan override. This function is used as the < operator when sorting. + avoid row invalidation if the model component is not ready + `Sorter::invalidate` is virtual. It provides more control to the derived classes
This commit is contained in:
parent
70b76297fd
commit
dae1dcaa13
|
@ -350,10 +350,10 @@ bool QQmlSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM
|
|||
{
|
||||
if (m_completed) {
|
||||
if (!m_sortRoleName.isEmpty()) {
|
||||
if (QSortFilterProxyModel::lessThan(source_left, source_right))
|
||||
return m_ascendingSortOrder;
|
||||
if (QSortFilterProxyModel::lessThan(source_right, source_left))
|
||||
return !m_ascendingSortOrder;
|
||||
if (m_ascendingSortOrder)
|
||||
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
||||
else
|
||||
return QSortFilterProxyModel::lessThan(source_right, source_left);
|
||||
}
|
||||
auto sortedSorters = m_sorters;
|
||||
std::stable_sort(sortedSorters.begin(),
|
||||
|
@ -364,8 +364,7 @@ bool QQmlSortFilterProxyModel::lessThan(const QModelIndex& source_left, const QM
|
|||
for(auto sorter : sortedSorters) {
|
||||
if (sorter->enabled()) {
|
||||
int comparison = sorter->compareRows(source_left, source_right, *this);
|
||||
if (comparison != 0)
|
||||
return comparison < 0;
|
||||
return comparison == -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ void ExpressionSorter::setExpression(const QQmlScriptString& scriptString)
|
|||
|
||||
void ExpressionSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
|
||||
{
|
||||
Sorter::proxyModelCompleted(proxyModel);
|
||||
updateContext(proxyModel);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ int FilterSorter::compare(const QModelIndex& sourceLeft, const QModelIndex& sour
|
|||
|
||||
void FilterSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
|
||||
{
|
||||
Sorter::proxyModelCompleted(proxyModel);
|
||||
|
||||
for (Filter* filter : qAsConst(m_filters))
|
||||
filter->proxyModelCompleted(proxyModel);
|
||||
}
|
||||
|
|
|
@ -107,21 +107,20 @@ void Sorter::setPriority(int priority)
|
|||
|
||||
int Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right, const QQmlSortFilterProxyModel& proxyModel) const
|
||||
{
|
||||
int comparison = compare(source_left, source_right, proxyModel);
|
||||
return (m_sortOrder == Qt::AscendingOrder) ? comparison : -comparison;
|
||||
if (m_sortOrder == Qt::AscendingOrder)
|
||||
return compare(source_left, source_right, proxyModel);
|
||||
else
|
||||
return compare(source_right, source_left, proxyModel);
|
||||
}
|
||||
|
||||
int Sorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
|
||||
{
|
||||
if (lessThan(sourceLeft, sourceRight, proxyModel))
|
||||
return -1;
|
||||
if (lessThan(sourceRight, sourceLeft, proxyModel))
|
||||
return 1;
|
||||
return 0;
|
||||
return lessThan(sourceLeft, sourceRight, proxyModel) ? -1 : 1;
|
||||
}
|
||||
|
||||
void Sorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
|
||||
{
|
||||
m_proxyCompleted = true;
|
||||
Q_UNUSED(proxyModel)
|
||||
}
|
||||
|
||||
|
@ -135,7 +134,7 @@ bool Sorter::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRi
|
|||
|
||||
void Sorter::invalidate()
|
||||
{
|
||||
if (m_enabled)
|
||||
if (m_enabled && m_proxyCompleted)
|
||||
Q_EMIT invalidated();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,12 +45,14 @@ Q_SIGNALS:
|
|||
protected:
|
||||
virtual int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
|
||||
virtual bool lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
|
||||
void invalidate();
|
||||
virtual void invalidate();
|
||||
|
||||
private:
|
||||
bool m_enabled = true;
|
||||
Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
|
||||
int m_priority = 0;
|
||||
|
||||
bool m_proxyCompleted = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue