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 <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2015-10-15 03:36:22 +02:00
parent be926e412c
commit 8515aa1871
2 changed files with 48 additions and 4 deletions

View File

@ -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;
}

View File

@ -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<QChar, PreallocatedPadding> padding;
};
PaddingResult padding(int len) const;