Details
-
Suggestion
-
Resolution: Done
-
P4: Low
-
None
-
None
-
a97862318a6b3f72a05a3e66ebcf5f0e455bb42a
Description
String comparison is an expensive operation. The comparison operators of QString and QByteArray could check if the shared data are not the same before doing a comparison of the memory.
For example:
bool QString::operator==(const QString &other) const { return (size() == other.size()) && (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0); }
could be rewritten as
bool QString::operator==(const QString &other) const { return (d == other.d) || ((size() == other.size()) && (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0)); }
Moreover, if two string have the the same data but different shared pointer, the data could be shared between the strings. This would reduce the memory usage and speed up the following calls to any comparison operator (but can be slower due to the call to free):
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index cb6a6be..1cfff34 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1908,8 +1908,31 @@ QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivi */ bool QString::operator==(const QString &other) const { - return (size() == other.size()) && - (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0); + if (d == other.d) { + return true; + } else if (size() == other.size() + && (memcmp((char*)unicode(),(char*)other.unicode(), size()*sizeof(QChar))==0)) { + const bool leftMajor = (d->ref) > (other.d->ref); + QString *rhs = const_cast<QString*>(&other); + QString *lhs = const_cast<QString*>(this); + + QString * major; + QString * minor; + if (leftMajor) { + major = lhs; + minor = rhs; + } else { + major = rhs; + minor = lhs; + } + major->d->ref.ref(); + Data *otherd = minor->d; + minor->d = major->d; + if (!otherd->ref.deref()) + free(otherd); + return true; + } + return false; } /*!