From 82147ce33a31e491c8363b78b50fbb9b1a2619de Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 25 Jan 2022 17:54:59 +0100 Subject: [PATCH] QString: optimize finding size=1 needles in QLatin1Strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Edward Welbourne --- src/corelib/text/qstring.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 9b13d4a276..6be5cd668e 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -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 s(needle.size()); qt_to_latin1_unchecked(reinterpret_cast(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(it) - haystack.data(); + return -1; + } + const QByteArrayMatcher matcher(needle); return matcher.indexIn(haystack, from); }