From dc41ff5a84a743eae04cacf64274f653c4b1397e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 3 Dec 2015 13:47:27 +0100 Subject: [PATCH] QMdiArea: fix quadratic behavior Repeatedly calling QVector::erase(it) (via QMutableVectorIterator::remove()) results in quadratic runtime. Use std::stable_partition, which does exactly what the old code tried to do, except in linear time. Change-Id: I6e5911ee781071bbb84d72449c969e3b9907da51 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/widgets/qmdiarea.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index 7ed790e40f..a0a6e08688 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -161,7 +161,6 @@ #include #include #include -#include #include #include #include @@ -480,17 +479,16 @@ QVector MinOverlapPlacer::getCandidatePlacements(const QSize &size, const */ QVector MinOverlapPlacer::findNonInsiders(const QRect &domain, QVector &source) { - QVector result; - result.reserve(source.size()); + const auto containedInDomain = + [domain](const QRect &srcRect) { return domain.contains(srcRect); }; - QMutableVectorIterator it(source); - while (it.hasNext()) { - const QRect srcRect = it.next(); - if (!domain.contains(srcRect)) { - result << srcRect; - it.remove(); - } - } + const auto firstOut = std::stable_partition(source.begin(), source.end(), containedInDomain); + + QVector result; + result.reserve(source.end() - firstOut); + std::copy(firstOut, source.end(), std::back_inserter(result)); + + source.erase(firstOut, source.end()); return result; }