summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2022-02-10 14:42:22 +0100
committerMarco Bubke <marco.bubke@qt.io>2022-02-15 17:18:11 +0000
commit38ab31cb8f3805203507ad2cc921e6f744dc6931 (patch)
treeca6dd527a58a743c5f03d7c081c4adf789e651ac
parent35480bc8e254e41b0ff408b8f486262a929302a7 (diff)
downloadqt-creator-38ab31cb8f3805203507ad2cc921e6f744dc6931.tar.gz
Utils: Optimize SmallString allocation
QStringEncoder returns a much higher size than normally need. Because allocations are not cheap the string is now copied to an temporary array on the stack if the required size is propably smaller than the small string optimization. The size is then computed from the transcoded string and used for the allocation. Change-Id: I1e1ef40094ad3040557bc5dd098a0b89006174c5 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/libs/utils/smallstring.h26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h
index f1a95d3a78..0f7b01c7f4 100644
--- a/src/libs/utils/smallstring.h
+++ b/src/libs/utils/smallstring.h
@@ -486,11 +486,31 @@ public:
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QStringEncoder encoder{QStringEncoder::Utf8};
+ constexpr size_type temporaryArraySize = Size * 6;
+
size_type oldSize = size();
- size_type newSize = oldSize + static_cast<size_type>(encoder.requiredSpace(string.size()));
+ size_type maximumRequiredSize = static_cast<size_type>(encoder.requiredSpace(oldSize));
+ char *newEnd = nullptr;
- reserve(optimalCapacity(newSize));
- auto newEnd = encoder.appendToBuffer(data() + size(), string);
+ if (maximumRequiredSize > temporaryArraySize) {
+ size_type newSize = oldSize + maximumRequiredSize;
+
+ reserve(optimalCapacity(newSize));
+ newEnd = encoder.appendToBuffer(data() + oldSize, string);
+ } else {
+ char temporaryArray[temporaryArraySize];
+
+ auto newTemporaryArrayEnd = encoder.appendToBuffer(temporaryArray, string);
+
+ auto newAppendedStringSize = newTemporaryArrayEnd - temporaryArray;
+ size_type newSize = oldSize + newAppendedStringSize;
+
+ reserve(optimalCapacity(newSize));
+
+ std::memcpy(data() + oldSize, temporaryArray, newAppendedStringSize);
+
+ newEnd = data() + newSize;
+ }
*newEnd = 0;
setSize(newEnd - data());
#else