From fa2153bd10057d7adbc5f5ededa1fd97c4a68161 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 8 Dec 2022 16:10:06 +0100 Subject: [PATCH] Optimize QXmlStreamWriterPrivate::doWriteToDevice(QStringView) Use a stack buffer, and perform the recoding from U16 to U8 in chunks. Since no-one so far managed to get a chunked QStringEncoder to produce the same output as the test expected, at least not without additional API, fall back to the raw QUtf8 functions. This also avoids the indirect function call overhead that QStringEncoder would entail. Fixes: QTBUG-109284 Change-Id: Icaa26c3988ac8506c9cf3fde18fd5892e5e63ef2 Reviewed-by: Fabian Kosmale --- src/corelib/serialization/qxmlstream.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 0aeef451bdd..e68544b1cf5 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -3063,13 +3063,19 @@ void QXmlStreamWriterPrivate::indent(int level) void QXmlStreamWriterPrivate::doWriteToDevice(QStringView s) { - QStringEncoder toUtf8(QStringEncoder::Utf8, QStringEncoder::Flag::Stateless); - QByteArray bytes = toUtf8(s); - if (toUtf8.hasError()) { - hasEncodingError = true; - return; + constexpr qsizetype MaxChunkSize = 512; + char buffer [3 * MaxChunkSize]; + QStringEncoder::State state; + while (!s.isEmpty()) { + const qsizetype chunkSize = std::min(s.size(), MaxChunkSize); + char *end = QUtf8::convertFromUnicode(buffer, s.first(chunkSize), &state); + if (state.remainingChars > 0) { + hasEncodingError = true; + return; + } + doWriteToDevice(QUtf8StringView{buffer, end}); + s = s.sliced(chunkSize); } - doWriteToDevice(QUtf8StringView{bytes}); } void QXmlStreamWriterPrivate::doWriteToDevice(QUtf8StringView s)