summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-06-08 11:17:11 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-08-04 09:28:41 +0000
commit4a40c717f3cf1ae181df49c91261a12d5e33e5a4 (patch)
tree1499ae2207288254e74d277629c3e9fb051a4dcc
parent31520c4fc0a7a7981e91145b6cff24d08a2ea81b (diff)
Optimize QString::compare_helper(QChar*, int, char*, int, cs)
... by using the recently-added QUtf8::convertToUnicode() and a QVarLengthArray instead of QString::fromUtf8(). Like elsewhere in QString, use a QVarLengthArray<ushort> instead of the more natural <QChar> to avoid instantiating another QVLA. Assume that length2 is usually set to a non-negative value. Not because that's necessarily the frequent case, but because a negative length2 leads to an expensive strlen, that usually dwarfs the additional branch cost. Check for data2 == nullptr early to avoid having to check it later twice. Change-Id: I04bda44ed857451efdf04c3283b5726480dd8c0d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qstring.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index a8e924b62d..8a86515fed 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -5450,9 +5450,15 @@ int QString::compare(QLatin1String other, Qt::CaseSensitivity cs) const Q_DECL_N
int QString::compare_helper(const QChar *data1, int length1, const char *data2, int length2,
Qt::CaseSensitivity cs)
{
- // ### optimize me
- const QString s2 = QString::fromUtf8(data2, length2 == -1 ? (data2 ? int(strlen(data2)) : -1) : length2);
- return compare_helper(data1, length1, s2.constData(), s2.size(), cs);
+ if (!data2)
+ return int(bool(data1));
+ if (Q_UNLIKELY(length2 < 0))
+ length2 = int(strlen(data2));
+ // ### make me nothrow in all cases
+ QVarLengthArray<ushort> s2(length2);
+ const auto beg = reinterpret_cast<QChar *>(s2.data());
+ const auto end = QUtf8::convertToUnicode(beg, data2, length2);
+ return compare_helper(data1, length1, beg, end - beg, cs);
}
/*!