From 9ede51d2140c026c03d1328de8c2704e9ee2f678 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 4 Nov 2020 14:08:41 +0100 Subject: [PATCH] Avoid calling memmove() if it's a noop This speeds up some of the operations. Change-Id: I5195ba79df92ead8e8003aa82681703e8c3afe99 Reviewed-by: Andrei Golubev Reviewed-by: Volker Hilsheimer Reviewed-by: Thiago Macieira --- src/corelib/tools/qarraydataops.h | 45 +++++++++++++++++-------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 7c12a84c10..957fa9e218 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -187,8 +187,9 @@ struct QArrayExceptionSafetyPrimitives Displacer(T *start, T *finish, qsizetype diff) noexcept : begin(start), end(finish), displace(diff) { - ::memmove(static_cast(begin + displace), static_cast(begin), - (end - begin) * sizeof(T)); + if (displace) + ::memmove(static_cast(begin + displace), static_cast(begin), + (end - begin) * sizeof(T)); } void commit() noexcept { displace = 0; } ~Displacer() noexcept @@ -216,8 +217,9 @@ struct QArrayExceptionSafetyPrimitives { } ~Mover() noexcept { - ::memmove(static_cast(destination), static_cast(source), - n * sizeof(T)); + if (destination != source) + ::memmove(static_cast(destination), static_cast(source), + n * sizeof(T)); size -= source > destination ? source - destination : destination - source; } }; @@ -292,8 +294,9 @@ public: Q_ASSERT(e <= where || b > this->end() || where == this->end()); // No overlap or append Q_ASSERT((e - b) <= this->freeSpaceAtEnd()); - ::memmove(static_cast(where + (e - b)), static_cast(where), - (static_cast(this->end()) - where) * sizeof(T)); + if (where != this->end()) + ::memmove(static_cast(where + (e - b)), static_cast(where), + (static_cast(this->end()) - where) * sizeof(T)); ::memcpy(static_cast(where), static_cast(b), (e - b) * sizeof(T)); this->size += (e - b); } @@ -307,10 +310,11 @@ public: Q_ASSERT(e <= where || b > this->end() || where == this->end()); // No overlap or append Q_ASSERT((e - b) <= this->freeSpaceAtBegin()); - auto oldBegin = this->begin(); + const T *oldBegin = this->begin(); this->ptr -= (e - b); - ::memmove(static_cast(this->begin()), static_cast(oldBegin), - (where - static_cast(oldBegin)) * sizeof(T)); + if (where != oldBegin) + ::memmove(static_cast(this->begin()), static_cast(oldBegin), + (where - oldBegin) * sizeof(T)); ::memcpy(static_cast(where - (e - b)), static_cast(b), (e - b) * sizeof(T)); this->size += (e - b); @@ -326,8 +330,9 @@ public: Q_ASSERT(where >= this->begin() && where <= this->end()); Q_ASSERT(size_t(this->freeSpaceAtEnd()) >= n); - ::memmove(static_cast(where + n), static_cast(where), - (static_cast(this->end()) - where) * sizeof(T)); + if (where != this->end()) + ::memmove(static_cast(where + n), static_cast(where), + (static_cast(this->end()) - where) * sizeof(T)); this->size += qsizetype(n); // PODs can't throw on copy while (n--) *where++ = t; @@ -340,10 +345,11 @@ public: Q_ASSERT(where >= this->begin() && where <= this->end()); Q_ASSERT(size_t(this->freeSpaceAtBegin()) >= n); - auto oldBegin = this->begin(); + const T *oldBegin = this->begin(); this->ptr -= n; - ::memmove(static_cast(this->begin()), static_cast(oldBegin), - (where - static_cast(oldBegin)) * sizeof(T)); + if (where != oldBegin) + ::memmove(static_cast(this->begin()), static_cast(oldBegin), + (where - oldBegin) * sizeof(T)); this->size += qsizetype(n); // PODs can't throw on copy where -= n; while (n--) @@ -392,8 +398,7 @@ public: auto oldBegin = this->begin(); --this->ptr; - ::memmove(static_cast(this->begin()), static_cast(oldBegin), - (where - oldBegin) * sizeof(T)); + ::memmove(static_cast(this->begin()), static_cast(oldBegin), (where - oldBegin) * sizeof(T)); *(where - 1) = t; } @@ -410,8 +415,8 @@ public: Q_ASSERT(b >= this->begin() && b < this->end()); Q_ASSERT(e > this->begin() && e <= this->end()); - ::memmove(static_cast(b), static_cast(e), - (static_cast(this->end()) - e) * sizeof(T)); + if (e != this->end()) + ::memmove(static_cast(b), static_cast(e), (static_cast(this->end()) - e) * sizeof(T)); this->size -= (e - b); } @@ -424,8 +429,8 @@ public: const auto oldBegin = this->begin(); this->ptr += (e - b); - ::memmove(static_cast(this->begin()), static_cast(oldBegin), - (b - static_cast(oldBegin)) * sizeof(T)); + if (b != oldBegin) + ::memmove(static_cast(this->begin()), static_cast(oldBegin), (b - static_cast(oldBegin)) * sizeof(T)); this->size -= (e - b); }