diff options
author | Marco Bubke <marco.bubke@qt.io> | 2022-02-10 14:42:22 +0100 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2022-02-15 17:18:11 +0000 |
commit | 38ab31cb8f3805203507ad2cc921e6f744dc6931 (patch) | |
tree | ca6dd527a58a743c5f03d7c081c4adf789e651ac | |
parent | 35480bc8e254e41b0ff408b8f486262a929302a7 (diff) | |
download | qt-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.h | 26 |
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 |