QVarLengthArray: Reduce memory allocations in emplace()

Currently, we allocate memory for elements one by one which can get
pretty slow when adding many elements.

[ChangeLog][QtCore][QVarLengthArray] Reduced number of memory
allocations in emplace() by allocating more memory at once.

Fixes: QTBUG-97489
Pick-to: 6.2
Change-Id: Idfb5b5946b047d5215c8ed00770574249f9f5d40
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Robert Löhning 2021-10-18 15:00:09 +02:00
parent fdbf7cdd09
commit a7d1c48ca3
2 changed files with 29 additions and 1 deletions

View File

@ -621,7 +621,8 @@ Q_OUTOFLINE_TEMPLATE auto QVarLengthArray<T, Prealloc>::emplace(const_iterator b
Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid");
qsizetype offset = qsizetype(before - ptr);
reserve(s + 1);
if (s == a)
reserve(s * 2);
if (!QTypeInfo<T>::isRelocatable) {
T *b = ptr + offset;
T *i = ptr + s;

View File

@ -180,6 +180,33 @@ void tst_QVarLengthArray::emplace()
QCOMPARE(&r, &strings.back());
QCOMPARE(strings.size(), 3);
QCOMPARE(strings.back(), QString(42, u'y'));
// test growing from empty arrays
QVarLengthArray<QString> emptyArrDefaultPrealloc;
QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
emptyArrDefaultPrealloc.emplace_back();
QCOMPARE(emptyArrDefaultPrealloc.size(), 1);
emptyArrDefaultPrealloc.resize(1024);
QCOMPARE(emptyArrDefaultPrealloc.size(), 1024);
emptyArrDefaultPrealloc.resize(0);
QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
emptyArrDefaultPrealloc.squeeze();
QCOMPARE(emptyArrDefaultPrealloc.size(), 0);
emptyArrDefaultPrealloc.emplace_back();
QCOMPARE(emptyArrDefaultPrealloc.size(), 1);
QVarLengthArray<QString, 1> emptyArrSmallPrealloc;
QCOMPARE(emptyArrSmallPrealloc.size(), 0);
emptyArrSmallPrealloc.emplace_back();
QCOMPARE(emptyArrSmallPrealloc.size(), 1);
emptyArrSmallPrealloc.resize(1024);
QCOMPARE(emptyArrSmallPrealloc.size(), 1024);
emptyArrSmallPrealloc.resize(0);
QCOMPARE(emptyArrSmallPrealloc.size(), 0);
emptyArrSmallPrealloc.squeeze();
QCOMPARE(emptyArrSmallPrealloc.size(), 0);
emptyArrSmallPrealloc.emplace_back();
QCOMPARE(emptyArrSmallPrealloc.size(), 1);
}
}