From b0a3cfaf53af5e7e306369d336b9d7e2763e62de Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Fri, 5 May 2023 19:17:27 +0300 Subject: [PATCH] QStringList: optimize replaceInStrings By first checking if the list has any matches before potentially making it detach. Change-Id: I7a42c2910ef6efc45033e562573414a3a9ef972e Reviewed-by: Thiago Macieira --- src/corelib/text/qstringlist.cpp | 29 +++++++++++++++++-- .../text/qstringlist/tst_qstringlist.cpp | 13 +++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/corelib/text/qstringlist.cpp b/src/corelib/text/qstringlist.cpp index 5e937b5555..92330c1aa4 100644 --- a/src/corelib/text/qstringlist.cpp +++ b/src/corelib/text/qstringlist.cpp @@ -363,7 +363,18 @@ QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegula void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView before, QStringView after, Qt::CaseSensitivity cs) { - for (qsizetype i = 0; i < that->size(); ++i) + // Before potentially detaching "that" list, check if any string contains "before" + qsizetype i = -1; + for (qsizetype j = 0; j < that->size(); ++j) { + if (that->at(j).contains(before, cs)) { + i = j; + break; + } + } + if (i == -1) + return; + + for (; i < that->size(); ++i) (*that)[i].replace(before.data(), before.size(), after.data(), after.size(), cs); } @@ -391,9 +402,21 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView befo \snippet qstringlist/main.cpp 5 \snippet qstringlist/main.cpp 17 */ -void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, const QString &after) +void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, + const QString &after) { - for (qsizetype i = 0; i < that->size(); ++i) + // Before potentially detaching "that" list, check if any string contains "before" + qsizetype i = -1; + for (qsizetype j = 0; j < that->size(); ++j) { + if (that->at(j).contains(re)) { + i = j; + break; + } + } + if (i == -1) + return; + + for (; i < that->size(); ++i) (*that)[i].replace(re, after); } #endif // QT_CONFIG(regularexpression) diff --git a/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp index 3a3cbd5a81..d8a3fb78df 100644 --- a/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp @@ -225,6 +225,19 @@ void tst_QStringList::replaceInStrings() list13.replaceInStrings( QString("a"), QStringView(QString("o")) ); list14 << "olpho" << "beto" << "gommo" << "epsilon"; QCOMPARE( list11, list12 ); + + QStringList list{"alpha", "beta", "gamma"}; + QStringList copy = list; + QVERIFY(!copy.isDetached()); + + // No matches, no detach + copy.replaceInStrings("z", "y"); + QVERIFY(!copy.isDetached()); + QCOMPARE(copy, list); + + copy.replaceInStrings("a", "y"); + QVERIFY(copy.isDetached()); + QCOMPARE(copy, (QStringList{"ylphy", "bety", "gymmy"})); } void tst_QStringList::contains()