QSortFilterProxyModel: port to PMF connects for performance reasons
BEFORE: 0.21 msecs per iteration (total: 56, iterations: 256) 801,946 CPU cycles per iteration (total: 801,946, iterations: 1) AFTER: 0.084 msecs per iteration (total: 87, iterations: 1024) 300,259 CPU cycles per iteration (total: 300,259, iterations: 1) Change-Id: I5b2703c217bb25e18f1d9f6a1eda19c60e1edcb0 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
parent
ad42833d33
commit
c609b8dba0
@ -109,9 +109,9 @@ private:
|
||||
|
||||
class QSortFilterProxyModelPrivate : public QAbstractProxyModelPrivate
|
||||
{
|
||||
public:
|
||||
Q_DECLARE_PUBLIC(QSortFilterProxyModel)
|
||||
|
||||
public:
|
||||
enum class Direction {
|
||||
Rows = 1,
|
||||
Columns = 2,
|
||||
@ -238,6 +238,8 @@ public:
|
||||
QModelIndexPairList saved_persistent_indexes;
|
||||
QList<QPersistentModelIndex> saved_layoutChange_parents;
|
||||
|
||||
std::array<QMetaObject::Connection, 18> sourceConnections;
|
||||
|
||||
QHash<QModelIndex, Mapping *>::const_iterator create_mapping(
|
||||
const QModelIndex &source_parent) const;
|
||||
QHash<QModelIndex, Mapping *>::const_iterator create_mapping_recursive(
|
||||
@ -2006,7 +2008,9 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
|
||||
QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent)
|
||||
: QAbstractProxyModel(*new QSortFilterProxyModelPrivate, parent)
|
||||
{
|
||||
connect(this, SIGNAL(modelReset()), this, SLOT(_q_clearMapping()));
|
||||
Q_D(QSortFilterProxyModel);
|
||||
QObjectPrivate::connect(this, &QSortFilterProxyModel::modelReset, d,
|
||||
&QSortFilterProxyModelPrivate::_q_clearMapping);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2031,56 +2035,10 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
|
||||
beginResetModel();
|
||||
|
||||
disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QList<int>)),
|
||||
this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QList<int>)));
|
||||
|
||||
disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||||
this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsInserted(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
|
||||
disconnect(d->model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
|
||||
this, SLOT(_q_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
|
||||
|
||||
disconnect(d->model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
|
||||
this, SLOT(_q_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
|
||||
|
||||
disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
|
||||
disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
|
||||
if (d->model) {
|
||||
for (const QMetaObject::Connection &connection : std::as_const(d->sourceConnections))
|
||||
disconnect(connection);
|
||||
}
|
||||
|
||||
// same as in _q_sourceReset()
|
||||
d->invalidatePersistentIndexes();
|
||||
@ -2088,57 +2046,61 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
|
||||
QAbstractProxyModel::setSourceModel(sourceModel);
|
||||
|
||||
connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QList<int>)),
|
||||
this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QList<int>)));
|
||||
d->sourceConnections = std::array<QMetaObject::Connection, 18>{
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::dataChanged, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceDataChanged),
|
||||
|
||||
connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||||
this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::headerDataChanged, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceHeaderDataChanged),
|
||||
|
||||
connect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsAboutToBeInserted, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted),
|
||||
|
||||
connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsInserted(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsInserted, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsInserted),
|
||||
|
||||
connect(d->model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsAboutToBeInserted, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted),
|
||||
|
||||
connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsInserted, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsInserted),
|
||||
|
||||
connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsAboutToBeRemoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeRemoved),
|
||||
|
||||
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsRemoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsRemoved),
|
||||
|
||||
connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsAboutToBeRemoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved),
|
||||
|
||||
connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
||||
this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsRemoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved),
|
||||
|
||||
connect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsAboutToBeMoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved),
|
||||
|
||||
connect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::rowsMoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceRowsMoved),
|
||||
|
||||
connect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsAboutToBeMoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved),
|
||||
|
||||
connect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||||
this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::columnsMoved, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceColumnsMoved),
|
||||
|
||||
connect(d->model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
|
||||
this, SLOT(_q_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::layoutAboutToBeChanged, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged),
|
||||
|
||||
connect(d->model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
|
||||
this, SLOT(_q_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::layoutChanged, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceLayoutChanged),
|
||||
|
||||
connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
|
||||
connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::modelAboutToBeReset, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset),
|
||||
|
||||
QObjectPrivate::connect(d->model, &QSortFilterProxyModel::modelReset, d,
|
||||
&QSortFilterProxyModelPrivate::_q_sourceReset)
|
||||
};
|
||||
endResetModel();
|
||||
if (d->update_source_sort_column() && d->dynamic_sortfilter)
|
||||
d->sort();
|
||||
|
@ -172,28 +172,6 @@ Q_SIGNALS:
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QSortFilterProxyModel)
|
||||
Q_DISABLE_COPY(QSortFilterProxyModel)
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(),
|
||||
void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right,
|
||||
const QList<int> &roles))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceReset())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_clearMapping())
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -31,6 +31,7 @@ class tst_QSortFilterProxyModel : public QObject
|
||||
private slots:
|
||||
void clearFilter_data();
|
||||
void clearFilter();
|
||||
void setSourceModel();
|
||||
|
||||
private:
|
||||
QStringList m_numberList; ///< Cache the strings for efficiency.
|
||||
@ -93,6 +94,19 @@ void tst_QSortFilterProxyModel::clearFilter()
|
||||
QCOMPARE(proxy.rowCount(), itemCount);
|
||||
}
|
||||
|
||||
void tst_QSortFilterProxyModel::setSourceModel()
|
||||
{
|
||||
QStringListModel model1;
|
||||
QStringListModel model2;
|
||||
|
||||
QSortFilterProxyModel proxy;
|
||||
|
||||
QBENCHMARK {
|
||||
proxy.setSourceModel(&model1);
|
||||
proxy.setSourceModel(&model2);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSortFilterProxyModel)
|
||||
|
||||
#include "tst_bench_qsortfilterproxymodel.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user