Using QString Effectively: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Remove non-functioning "toc" command)
Line 40: Line 40:
= QStringBuilder : Fast QString concatenation =
= QStringBuilder : Fast QString concatenation =


The code below requires atleast 2 mallocs. First a malloc to store the result of "(" + type. And then another malloc for appending the ")". The number of mallocs increases with each addition of "''" operator.
The code below requires atleast 2 mallocs. First a malloc to store the result of "(" + type. And then another malloc for appending the ")". The number of mallocs increases with each addition of {{#tag:syntaxhighlight|{{{|operator +}}}|lang={{{lang|cpp}}}|enclose=none}}.
<code>
<code>
  if (foo.startsWith("("'' type + ")"))
  if (foo.startsWith("(" + type + ")"))
</code>
</code>


The additional mallocs can be avoided if the length of the final QString is known in advance. Qt 4.6 introduces an internal class called QStringBuilder that "reserves" memory for a concatenation chain in a single shot. It does so by having each of the + operations above return a different class (not QString anymore). This class keeps track of the string's that are being appended and the required memory at each step. At the final step, when the concatenation operation gets converted into a QString it allocates memory in a single shot and copies all the strings in the chain one after another. This feature can be enabled by including <QtCore/QStringBuilder>. and using use the operator '' instead of ''''. One would now write,
The additional mallocs can be avoided if the length of the final QString is known in advance. Qt 4.6 introduces an internal class called QStringBuilder that "reserves" memory for a concatenation chain in a single shot. It does so by having each of the + operations above return a different class (not QString anymore). This class keeps track of the string's that are being appended and the required memory at each step. At the final step, when the concatenation operation gets converted into a QString it allocates memory in a single shot and copies all the strings in the chain one after another. This feature can be enabled by including <QtCore/QStringBuilder> and using the operator% instead of {{#tag:syntaxhighlight|{{{|operator +}}}|lang={{{lang|cpp}}}|enclose=none}}. One would now write,
<code>
<code>
  if (foo.startsWith("(" % type % ")"))
  if (foo.startsWith("(" % type % ")"))
</code>
</code>


'''' can be used instead of '' by defining QT_USE_QSTRINGBUILDER. See [http://developer.qt.nokia.com/doc/qt-4.8/qstring.html#more-efficient-string-construction Fast concatenation] for more details
{{#tag:syntaxhighlight|{{{|operator +}}}|lang={{{lang|cpp}}}|enclose=none}} can be used instead of {{#tag:syntaxhighlight|{{{|operator %}}}|lang={{{lang|cpp}}}|enclose=none}} by defining QT_USE_QSTRINGBUILDER. See [http://developer.qt.nokia.com/doc/qt-4.8/qstring.html#more-efficient-string-construction Fast concatenation] for more details.


= QStringMatcher : Fast string matching =
= QStringMatcher : Fast string matching =

Revision as of 13:34, 25 July 2015

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

English 简体中文 Български


Written By : Girish Ramakrishnan, ForwardBias Technologies

This page explains the purpose of various QString related classes.

QLatin1String : Avoid hidden mallocs in operator "=="

Creating a QString from a C-string may involve a malloc. For example, there is possibly a hidden-malloc cost in the following code.

 if (fruit == "apple") {  } // possibly hidden malloc

QString provides a QString::operator==(const char *) overload for comparison with C-strings. As explained in QtString, the encoding of C-strings is determined using QTextCodec::setCodecForCStrings(). When no special encoding is set, Qt performs the above comparison by providing a specialized function that compares a Unicode string (fruit) and the Latin-1 string ('apple'). This comparison is fast and requires no mallocs.

However, when QTextCodec::setCodecForCString is set, "apple" gets converted into a QString using QString::fromAscii(). This means that QString will allocate memory for the string "apple" and creates a deep copy of the C-style string before performing the comparison!

Application developers set QTextCodec::setCodecForCString() in main() without realizing that this has the side-effect of a malloc for every single C-style string comparison.

Since comparisons with Latin-1 C-strings are very common in programs, Qt provides a special class called QLatin1String that just holds a pointer to a Latin-1 encoded C-string. In addition, QString provides a QString::operator(const QLatin1String &) overload that calls the specialized function that compares the Unicode string and Latin1-string. We can make the above code assuredly fast by writing it instead as,

    if (fruit QLatin1String("apple")) {  } // fast and mentions encoding

In Qt's own code, all C-strings comparisons use QLatin1String since the application can choose an arbitrary codec for C-strings.

QStringRef : String manipulation without the malloc

QString has various methods for string manipulations like mid(), left(), right(). All of them create a new QString and hence a malloc/deep copy of data in an existing QString. Instead, QString::midRef(), QString::leftRef() and QString::rightRef() can be used to obtain a QStringRef. A QStringRef is a reference of a portion of a QString. QString also provides many overloads like QString::operator==(const QStringRef &) for optimal use with QStringRef.

QString::reserve and QString::squeeze

It's better to call QString::reserve to allocate extra memory in advance so that every call to QString::append() does not result in a malloc. Extra memory can be reclaimed using QString::squeeze.

QStringBuilder : Fast QString concatenation

The code below requires atleast 2 mallocs. First a malloc to store the result of "(" + type. And then another malloc for appending the ")". The number of mallocs increases with each addition of operator +.

 if (foo.startsWith("(" + type + ")"))

The additional mallocs can be avoided if the length of the final QString is known in advance. Qt 4.6 introduces an internal class called QStringBuilder that "reserves" memory for a concatenation chain in a single shot. It does so by having each of the + operations above return a different class (not QString anymore). This class keeps track of the string's that are being appended and the required memory at each step. At the final step, when the concatenation operation gets converted into a QString it allocates memory in a single shot and copies all the strings in the chain one after another. This feature can be enabled by including <QtCore/QStringBuilder> and using the operator% instead of operator +. One would now write,

 if (foo.startsWith("(" % type % ")"))

operator + can be used instead of operator % by defining QT_USE_QSTRINGBUILDER. See Fast concatenation for more details.

QStringMatcher : Fast string matching