From 1a9f8cc0df33195df959cee2e355dde4cbacd754 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 20 Dec 2024 22:00:32 +0100 Subject: Fix a performance regression in QDataStream Commit e176dd78fd2f253eb2625585b2bd90b5713e5984 replaced a `new char[n]` with a std::make_unique(n), probably on this author's insistence. But the two are not equivalent: make_unique() value-initializes, even arrays, even of built-in type, which means that each buffer resize writes each byte twice: first nulling out the whole buffer as part of value-initialization, then in the memcpy() and any following read()s. For buffers of several MiB, or even GiB in size, this is very costly. Fix by adding and using a backport of C++20 make_unique_for_overwrite(), which performs the equivalent of the old code (ie. default-, not value-initialization). Also add q20::is_(un)bounded_array, which are needed for the implementation of q20::make_unique_for_overwrite(). Amends e176dd78fd2f253eb2625585b2bd90b5713e5984. Pick-to: 6.9 6.8 6.5 Change-Id: I8865c7369e522ec475df122e3d00d6aba3b24561 Reviewed-by: Thiago Macieira --- src/corelib/serialization/qdatastream.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/corelib/serialization/qdatastream.cpp') diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index 039c8fbcdc3..f9c08cd78e4 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -13,6 +13,8 @@ #include #include "qendian.h" +#include + QT_BEGIN_NAMESPACE constexpr quint32 QDataStream::NullCode; @@ -1096,7 +1098,7 @@ QDataStream &QDataStream::readBytes(char *&s, qint64 &l) do { qsizetype blockSize = qMin(step, len - allocated); const qsizetype n = allocated + blockSize + 1; - if (const auto prevBuf = std::exchange(curBuf, std::make_unique(n))) + if (const auto prevBuf = std::exchange(curBuf, q20::make_unique_for_overwrite(n))) memcpy(curBuf.get(), prevBuf.get(), allocated); if (readBlock(curBuf.get() + allocated, blockSize) != blockSize) return *this; -- cgit v1.2.3