diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-06-08 11:17:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-08-04 09:28:41 +0000 |
commit | 4a40c717f3cf1ae181df49c91261a12d5e33e5a4 (patch) | |
tree | 1499ae2207288254e74d277629c3e9fb051a4dcc | |
parent | 31520c4fc0a7a7981e91145b6cff24d08a2ea81b (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.cpp | 12 |
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); } /*! |