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>
This commit is contained in:
parent
cc6324665e
commit
5f73f48556
@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -2803,6 +2803,7 @@ void tst_QString::insert_data(DataOptions options)
|
||||
QTest::newRow("a.insert(1, ba)") << a << baC << 1 << (a + ba);
|
||||
QTest::newRow("ba.insert(1, a)") << ba << aC << 1 << (ba + a);
|
||||
QTest::newRow("ba.insert(2, b)") << ba << bC << 2 << (ba + b);
|
||||
QTest::newRow("ba.insert(10, b)") << ba << bC << 10 << (ba + QString(10 - ba.size(), u' ') + b);
|
||||
|
||||
QTest::newRow("null-insert-0-yumlaut") << null << yumlautC << 0 << yumlaut;
|
||||
QTest::newRow("empty-insert-0-yumlaut") << empty << yumlautC << 0 << yumlaut;
|
||||
|
Loading…
Reference in New Issue
Block a user