From 8515aa18716779985a5955292524fd683528c576 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Oct 2015 03:36:22 +0200 Subject: [PATCH] QTextStream: optimize streaming of QLatin1String and const char* Instead of converting the QLatin1String to a QString at the first opportunity, keep it around until it is appended to one of the internal QStrings in write(). Avoids a memory allocation per QLatin1String / const char* streamed. Change-Id: Id973a9b743e5a6696defbc4ef4ed2db1ef54e9cc Reviewed-by: Thiago Macieira --- src/corelib/io/qtextstream.cpp | 48 +++++++++++++++++++++++++++++++--- src/corelib/io/qtextstream_p.h | 4 ++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 3c9385c625..a8fd2dd7ab 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -844,6 +844,21 @@ inline void QTextStreamPrivate::write(QChar ch) } } +/*! + \internal +*/ +void QTextStreamPrivate::write(QLatin1String data) +{ + if (string) { + // ### What about seek()?? + string->append(data); + } else { + writeBuffer += data; + if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE) + flushWriteBuffer(); + } +} + /*! \internal */ @@ -958,6 +973,34 @@ void QTextStreamPrivate::putString(const QChar *data, int len, bool number) } } +/*! + \internal +*/ +void QTextStreamPrivate::putString(QLatin1String data, bool number) +{ + if (Q_UNLIKELY(params.fieldWidth > data.size())) { + + // handle padding + + const PaddingResult pad = padding(data.size()); + + if (params.fieldAlignment == QTextStream::AlignAccountingStyle && number) { + const QChar sign = data.size() > 0 ? QLatin1Char(*data.data()) : QChar(); + if (sign == locale.negativeSign() || sign == locale.positiveSign()) { + // write the sign before the padding, then skip it later + write(&sign, 1); + data = QLatin1String(data.data() + 1, data.size() - 1); + } + } + + write(pad.padding.constData(), pad.left); + write(data); + write(pad.padding.constData(), pad.right); + } else { + write(data); + } +} + /*! Constructs a QTextStream. Before you can use it for reading or writing, you must assign a device or a string. @@ -2529,14 +2572,13 @@ QTextStream &QTextStream::operator<<(const QString &string) \overload Writes \a string to the stream, and returns a reference to the - QTextStream. The contents of \a string are converted with the - QString constructor that takes a QLatin1String as argument. + QTextStream. */ QTextStream &QTextStream::operator<<(QLatin1String string) { Q_D(QTextStream); CHECK_VALID_STREAM(*this); - d->putString(QString(string)); + d->putString(string); return *this; } diff --git a/src/corelib/io/qtextstream_p.h b/src/corelib/io/qtextstream_p.h index c44ae5dada..115408a6dd 100644 --- a/src/corelib/io/qtextstream_p.h +++ b/src/corelib/io/qtextstream_p.h @@ -168,15 +168,17 @@ public: inline void write(const QString &data) { write(data.begin(), data.length()); } inline void write(QChar ch); void write(const QChar *data, int len); + void write(QLatin1String data); inline void putString(const QString &ch, bool number = false) { putString(ch.constData(), ch.length(), number); } void putString(const QChar *data, int len, bool number = false); + void putString(QLatin1String data, bool number = false); inline void putChar(QChar ch); void putNumber(qulonglong number, bool negative); struct PaddingResult { enum { PreallocatedPadding = 80 }; // typical line length - int right, left; + int left, right; QVarLengthArray padding; }; PaddingResult padding(int len) const;