From a4e4c3100780be27070c8916d25a9f7c461d1e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Thu, 16 Feb 2012 10:12:30 +0100 Subject: QHeaderview - many sections removed performance boost. When the QHeaderView model rowCount is decreased then the headerview needs to remove some sections. If e.g swapSections had occured then qheaderview before this patch did a very slow removal by removing one section at a time and for each section it restored visual and logical indexes. By temporarily storing the logical index on the section we can reduce the execution time of this a lot. The old code is only faster when we remove one index (and is kept for that situation) There is a complexity in difference (and many factors in our qheaderview benchmark (the trunc part)) Change-Id: If45eab17fbca3364d458b004980570b5d013e4bd Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qheaderview.cpp | 24 ++++++++++++++++++++++-- src/widgets/itemviews/qheaderview_p.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src/widgets/itemviews') diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 299dcb3dd4..6a1f949258 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1799,7 +1799,8 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent, //Q_ASSERT(headerSectionCount() == sectionCount); removeSectionsFromSpans(logicalFirst, logicalLast); } else { - for (int l = logicalLast; l >= logicalFirst; --l) { + if (logicalFirst == logicalLast) { // Remove just one index. + int l = logicalFirst; int visual = visualIndices.at(l); for (int v = 0; v < sectionCount; ++v) { if (v >= logicalIndices.count()) @@ -1815,8 +1816,27 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent, visualIndices.remove(l); //Q_ASSERT(headerSectionCount() == sectionCount); removeSectionsFromSpans(visual, visual); + } else { + sectionStartposRecalc = true; // We will need to recalc positions after removing items + for (int u = 0; u < sectionSpans.count(); ++u) // Store spans info + sectionSpans.at(u).tmpLogIdx = logicalIndices.at(u); + for (int v = sectionSpans.count() - 1; v >= 0; --v) { // Remove the sections + if (logicalFirst <= sectionSpans.at(v).tmpLogIdx && sectionSpans.at(v).tmpLogIdx <= logicalLast) + removeSectionsFromSpans(v, v); // Invalidates the spans variable + } + visualIndices.resize(sectionSpans.count()); + logicalIndices.resize(sectionSpans.count()); + int* visual_data = visualIndices.data(); + int* logical_data = logicalIndices.data(); + for (int w = 0; w < sectionSpans.count(); ++w) { // Restore visual and logical indexes + int logindex = sectionSpans.at(w).tmpLogIdx; + if (logindex > logicalFirst) + logindex -= changeCount; + visual_data[logindex] = w; + logical_data[w] = logindex; + } } - // ### handle sectionSelection, sectionHidden + // ### handle sectionSelection (sectionHidden is handled by updateHiddenSections) } sectionCount -= changeCount; diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index 9d7d97f582..4d1f4ba5a0 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -288,6 +288,7 @@ public: struct SectionSpan { int size; mutable int calculated_startpos; + mutable int tmpLogIdx; QHeaderView::ResizeMode resizeMode; inline SectionSpan() : size(0), resizeMode(QHeaderView::Interactive) {} inline SectionSpan(int length, QHeaderView::ResizeMode mode) -- cgit v1.2.3