QString: optimize finding size=1 needles in QLatin1Strings

Use memchr() if the needle has size() one, and add a fast path in
findString(QLatin1String, QStringView) to circumvent the QVLA path. We
might want to extend this and use a simple C array for very short
needles and (cached?) Boyer-Moore for anything larger.

Pick-to: 6.3
Change-Id: I8364ea9f004d537be8a09cc751408d8adb902d13
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2022-01-25 17:54:59 +01:00
parent 7b7c3355f2
commit 82147ce33a

View File

@ -10477,6 +10477,11 @@ qsizetype QtPrivate::findString(QLatin1String haystack, qsizetype from, QStringV
if (!QtPrivate::isLatin1(needle)) // won't find non-L1 UTF-16 needles in a L1 haystack!
return -1;
if (needle.size() == 1) {
const char n = needle.front().toLatin1();
return QtPrivate::findString(haystack, from, QLatin1String(&n, 1), cs);
}
QVarLengthArray<char> s(needle.size());
qt_to_latin1_unchecked(reinterpret_cast<uchar *>(s.data()), needle.utf16(), needle.size());
return QtPrivate::findString(haystack, from, QLatin1String(s.data(), s.size()), cs);
@ -10495,6 +10500,14 @@ qsizetype QtPrivate::findString(QLatin1String haystack, qsizetype from, QLatin1S
return from;
if (cs == Qt::CaseSensitive) {
if (needle.size() == 1) {
Q_ASSUME(haystack.data() != nullptr); // see size check above
if (auto it = memchr(haystack.data() + from, needle.front().toLatin1(), adjustedSize))
return static_cast<const char *>(it) - haystack.data();
return -1;
}
const QByteArrayMatcher matcher(needle);
return matcher.indexIn(haystack, from);
}