Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Using QString Effectively: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Convert ExpressionEngine links)
(Decode HTML entity names)
Line 24: Line 24:
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.
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,
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,
<code>
<code>
     if (fruit QLatin1String("apple")) { … } // fast and mentions encoding
     if (fruit QLatin1String("apple")) { … } // fast and mentions encoding
Line 33: Line 33:
= QStringRef : String manipulation without the malloc =
= 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 &amp;) for optimal use with QStringRef.
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 =
= QString::reserve and QString::squeeze =

Revision as of 17:54, 12 March 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 简体中文 Български

[toc align_right="yes" depth="1"]

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 use the operator instead of ''. One would now write,

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

'' can be used instead of by defining QT_USE_QSTRINGBUILDER. See Fast concatenation for more details

QStringMatcher : Fast string matching