summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-11-04 12:07:06 +0100
committerAndrei Golubev <andrei.golubev@qt.io>2020-11-09 17:36:09 +0100
commit1d309843a1df3082a5c989a2bb46fd0b8e01f83a (patch)
tree9ddba6a7f5fcb886753b157b6b38275a4ff1494c /src
parent2768270573c2707add47aebbfbbadaecaf828eec (diff)
Move existing items when inserting instead of copying them
Use move operations to move existing items instead of copying them. This speeds up insertions for non relocatable types significantly (e.g. for std::string). Change-Id: I308f381ac2242e50505f02675c2d2afbf21069d1 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qarraydataops.h61
1 files changed, 28 insertions, 33 deletions
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index fc9c5dbe7f..0e067bbbe5 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -566,8 +566,8 @@ public:
// Array may be truncated at where in case of exceptions
- T *const end = this->end();
- const T *readIter = end;
+ T *end = this->end();
+ T *readIter = end;
T *writeIter = end + (e - b);
const T *const step1End = where + qMax(e - b, end - where);
@@ -578,7 +578,7 @@ public:
while (writeIter != step1End) {
--readIter;
// If exception happens on construction, we should not call ~T()
- new (writeIter - 1) T(*readIter);
+ new (writeIter - 1) T(std::move(*readIter));
--writeIter;
}
@@ -596,7 +596,7 @@ public:
while (readIter != where) {
--readIter;
--writeIter;
- *writeIter = *readIter;
+ *writeIter = std::move(*readIter);
}
while (writeIter != where) {
@@ -617,8 +617,8 @@ public:
typedef typename QArrayExceptionSafetyPrimitives<T>::template Destructor<T *> Destructor;
- T *const begin = this->begin();
- const T *readIter = begin;
+ T *begin = this->begin();
+ T *readIter = begin;
T *writeIter = begin - (e - b);
const T *const step1End = where - qMax(e - b, where - begin);
@@ -627,7 +627,7 @@ public:
// Construct new elements in array
while (writeIter != step1End) {
- new (writeIter) T(*readIter);
+ new (writeIter) T(std::move(*readIter));
++readIter;
++writeIter;
}
@@ -644,7 +644,7 @@ public:
// Copy assign over existing elements
while (readIter != where) {
- *writeIter = *readIter;
+ *writeIter = std::move(*readIter);
++readIter;
++writeIter;
}
@@ -669,8 +669,8 @@ public:
typedef typename QArrayExceptionSafetyPrimitives<T>::template Destructor<T *> Destructor;
// Array may be truncated at where in case of exceptions
- T *const end = this->end();
- const T *readIter = end;
+ T *end = this->end();
+ T *readIter = end;
T *writeIter = end + n;
const T *const step1End = where + qMax<size_t>(n, end - where);
@@ -681,7 +681,7 @@ public:
while (writeIter != step1End) {
--readIter;
// If exception happens on construction, we should not call ~T()
- new (writeIter - 1) T(*readIter);
+ new (writeIter - 1) T(std::move(*readIter));
--writeIter;
}
@@ -699,7 +699,7 @@ public:
while (readIter != where) {
--readIter;
--writeIter;
- *writeIter = *readIter;
+ *writeIter = std::move(*readIter);
}
while (writeIter != where) {
@@ -718,8 +718,8 @@ public:
typedef typename QArrayExceptionSafetyPrimitives<T>::template Destructor<T *> Destructor;
- T *const begin = this->begin();
- const T *readIter = begin;
+ T *begin = this->begin();
+ T *readIter = begin;
T *writeIter = begin - n;
const T *const step1End = where - qMax<size_t>(n, where - begin);
@@ -728,7 +728,7 @@ public:
// Construct new elements in array
while (writeIter != step1End) {
- new (writeIter) T(*readIter);
+ new (writeIter) T(std::move(*readIter));
++readIter;
++writeIter;
}
@@ -744,7 +744,7 @@ public:
// Copy assign over existing elements
while (readIter != where) {
- *writeIter = *readIter;
+ *writeIter = std::move(*readIter);
++readIter;
++writeIter;
}
@@ -1225,23 +1225,18 @@ public:
detached->copyAppend(where, this->constEnd());
this->swap(detached);
} else {
- // we're detached and we can just move data around
- if (i == this->size && n <= this->freeSpaceAtEnd()) {
- copyAppend(n, t);
- } else {
- T copy(t);
- // Insert elements based on the divided distance. Good case: only 1
- // insert happens (either to the front part or to the back part). Bad
- // case: both inserts happen, meaning that we touch all N elements in
- // the container (this should be handled "outside" by ensuring enough
- // free space by reallocating more frequently)
- T *where = this->begin() + i;
- const auto beginSize = sizeToInsertAtBegin(where, n);
- if (beginSize)
- Base::insert(GrowsBackwardsTag{}, where, beginSize, copy);
- if (n - beginSize)
- Base::insert(GrowsForwardTag{}, where, n - beginSize, copy);
- }
+ T copy(t);
+ // Insert elements based on the divided distance. Good case: only 1
+ // insert happens (either to the front part or to the back part). Bad
+ // case: both inserts happen, meaning that we touch all N elements in
+ // the container (this should be handled "outside" by ensuring enough
+ // free space by reallocating more frequently)
+ T *where = this->begin() + i;
+ const auto beginSize = sizeToInsertAtBegin(where, n);
+ if (beginSize)
+ Base::insert(GrowsBackwardsTag{}, where, beginSize, copy);
+ if (n - beginSize)
+ Base::insert(GrowsForwardTag{}, where, n - beginSize, copy);
}
}