aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <[email protected]>2025-05-16 09:43:21 +0200
committerChristian Kandeler <[email protected]>2025-05-16 14:29:37 +0000
commit728ed321cf459ca1a1e85492ca7b47b45ebe60f4 (patch)
treedd8da6a4e65091a91a2bfa94930bbca016d62b1b
parent811c196c4ec0f0167b1e296f3412d2ae0304f839 (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.cpp30
-rw-r--r--src/libs/utils/treemodel.h1
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.