diff options
author | Christian Kandeler <[email protected]> | 2025-05-16 09:43:21 +0200 |
---|---|---|
committer | Christian Kandeler <[email protected]> | 2025-05-16 14:29:37 +0000 |
commit | 728ed321cf459ca1a1e85492ca7b47b45ebe60f4 (patch) | |
tree | dd8da6a4e65091a91a2bfa94930bbca016d62b1b | |
parent | 811c196c4ec0f0167b1e296f3412d2ae0304f839 (diff) |
Utils: Speed up TreeItem::updateAll()
Get rid of reverse lookups and minimize calls to dataChanged().
Also clarify the comment in TreeItem::indexOf().
Change-Id: Ie7c69aab4bc598b3ae79ab76b8e46cb4f7ca63c8
Reviewed-by: hjk <[email protected]>
-rw-r--r-- | src/libs/utils/treemodel.cpp | 30 | ||||
-rw-r--r-- | src/libs/utils/treemodel.h | 1 |
2 files changed, 22 insertions, 9 deletions
diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 37d9876a990..66d26360987 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -615,9 +615,8 @@ TreeItem *TreeItem::childAt(int pos) const int TreeItem::indexOf(const TreeItem *item) const { - // !!! Do not replace this loop without benchmarking !!! - // At the time of writing, std::find() is slower by a factor of 3.5. - // The same goes for QList::indexOf(). + // We use a handwritten loop here because QList::indexOf() is considerably slower + // in debug mode due to the use of iterators. for (qsizetype i = 0, n = m_children.size(); i < n; ++i) if (m_children.at(i) == item) return int(i); @@ -760,12 +759,25 @@ void TreeItem::update() void TreeItem::updateAll() { - if (m_model) { - QModelIndex idx = index(); - emit m_model->dataChanged(idx, idx.sibling(idx.row(), m_model->m_columnCount - 1)); - for (TreeItem *item : *this) - item->updateAll(); - } + update(); + updateChildrenRecursively(); +} + +void TreeItem::updateChildrenRecursively() +{ + if (!m_model) + return; + + const qsizetype rowCount = m_children.size(); + if (rowCount == 0) + return; + const QModelIndex topLeft = m_model->createIndex(0, 0, m_children.first()); + const QModelIndex bottomRight = rowCount == 1 && m_model->m_columnCount == 1 + ? topLeft + : m_model->createIndex(m_children.size() - 1, m_model->m_columnCount - 1, m_children.last()); + emit m_model->dataChanged(topLeft, bottomRight); + for (TreeItem * const item : std::as_const(m_children)) + item->updateChildrenRecursively(); } void TreeItem::updateColumn(int column) diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 7d7a330086f..81fd042a806 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -81,6 +81,7 @@ private: void clear(); void removeItemAt(int pos); void propagateModel(BaseTreeModel *m); + void updateChildrenRecursively(); TreeItem *m_parent = nullptr; // Not owned. BaseTreeModel *m_model = nullptr; // Not owned. |