summaryrefslogtreecommitdiffstats
path: root/src/corelib/text
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2022-12-11 15:31:33 +0200
committerAhmad Samir <a.samirh78@gmail.com>2023-02-09 16:49:54 +0200
commit5f73f485563719e133c849c8dbd93877095d5ff5 (patch)
tree5a14e53691a46fa0ec6cda5395de147a0dc27e8d /src/corelib/text
parentcc6324665eb61eca136e9057ce1c72a2a0c32d31 (diff)
QString: optimize insert(qsizetype, QUtf8StringView)
Utf8 data is variable-width, ideally we want to write characters at most once, so insert directly into the QString buffer if inserting at the end (by delegating to append(QUtf8SV)), and use an intermediate buffer to hold the converted data before inserting anywhere else. Task-number: QTBUG-108546 Change-Id: Iabfaeecaf34a1ba11946bd67951e69a45d954d6d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/text')
-rw-r--r--src/corelib/text/qstring.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index daa8f8d98b..b6c36e1b2f 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -2939,7 +2939,9 @@ QString &QString::operator=(QChar ch)
defined.
*/
-
+/*! \internal
+ T is a view or a container on/of QChar, char16_t, or char
+*/
template <typename T>
static void insert_helper(QString &str, qsizetype i, T toInsert)
{
@@ -3021,7 +3023,32 @@ QString &QString::insert(qsizetype i, QLatin1StringView str)
*/
QString &QString::insert(qsizetype i, QUtf8StringView s)
{
- return insert(i, s.toString()); // ### optimize (QTBUG-108546)
+ auto insert_size = s.size();
+ if (i < 0 || insert_size <= 0)
+ return *this;
+
+ qsizetype difference = 0;
+ if (Q_UNLIKELY(i > d.size))
+ difference = i - d.size;
+
+ if (i >= d.size) {
+ d.detachAndGrow(QArrayData::GrowsAtEnd, difference + insert_size, nullptr, nullptr);
+ Q_CHECK_PTR(d.data());
+
+ if (difference > 0)
+ resize(i, u' ');
+ append(s);
+ } else {
+ // Optimal insertion of Utf8 data is at the end, anywhere else could
+ // potentially lead to moving characters twice if Utf8 data size
+ // (variable-width) is less than the equiavalent Utf16 data size
+ QVarLengthArray<char16_t> buffer(insert_size); // ### optimize (QTBUG-108546)
+ char16_t *b = QUtf8::convertToUnicode(buffer.data(), s);
+ buffer.resize(std::distance(buffer.begin(), b));
+ insert_helper(*this, i, buffer);
+ }
+
+ return *this;
}
/*!