QtBase: use new QStaticByteArrayMatcher where applicable

Even for compilers that don't yet support C++14 constexpr,
this should improve performance of searches a lot, if,
indeed, Boyer-Moore still is an optimization over linear
searching at all in these days of hardware prefetchers
and deep CPU pipelines, because the setup cost is only
incurred once. As function-statics, we also don't care
about startup ordering and cost.

It's a pity that the platform that would benefit the most
- Windows - doesn't have constexpr support, yet.

Change-Id: I827df135854fd6fbd6546e248dc37ef0fbaf1792
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
This commit is contained in:
Marc Mutz 2016-02-25 03:54:13 +01:00
parent 93570810d8
commit bfcc2902a4
3 changed files with 21 additions and 9 deletions

View File

@ -43,6 +43,7 @@
#ifndef QT_NO_TEXTCODEC #ifndef QT_NO_TEXTCODEC
#include "qbytearraymatcher.h"
#include "qlist.h" #include "qlist.h"
#include "qfile.h" #include "qfile.h"
#include "qstringlist.h" #include "qstringlist.h"
@ -1092,10 +1093,12 @@ QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba, QTextCodec *defaultCo
// determine charset // determine charset
QTextCodec *c = QTextCodec::codecForUtfText(ba, 0); QTextCodec *c = QTextCodec::codecForUtfText(ba, 0);
if (!c) { if (!c) {
static Q_RELAXED_CONSTEXPR auto matcher = qMakeStaticByteArrayMatcher("meta ");
QByteArray header = ba.left(1024).toLower(); QByteArray header = ba.left(1024).toLower();
int pos = header.indexOf("meta "); int pos = matcher.indexIn(header);
if (pos != -1) { if (pos != -1) {
pos = header.indexOf("charset=", pos); static Q_RELAXED_CONSTEXPR auto matcher = qMakeStaticByteArrayMatcher("charset=");
pos = matcher.indexIn(header, pos);
if (pos != -1) { if (pos != -1) {
pos += qstrlen("charset="); pos += qstrlen("charset=");

View File

@ -42,6 +42,7 @@
#ifndef QT_NO_IMAGEFORMAT_XPM #ifndef QT_NO_IMAGEFORMAT_XPM
#include <private/qcolor_p.h> #include <private/qcolor_p.h>
#include <qbytearraymatcher.h>
#include <qimage.h> #include <qimage.h>
#include <qmap.h> #include <qmap.h>
#include <qtextstream.h> #include <qtextstream.h>
@ -1041,7 +1042,9 @@ bool qt_read_xpm_image_or_array(QIODevice *device, const char * const * source,
if ((readBytes = device->readLine(buf.data(), buf.size())) < 0) if ((readBytes = device->readLine(buf.data(), buf.size())) < 0)
return false; return false;
if (buf.indexOf("/* XPM") != 0) { static Q_RELAXED_CONSTEXPR auto matcher = qMakeStaticByteArrayMatcher("/* XPM");
if (matcher.indexIn(buf) != 0) {
while (readBytes > 0) { while (readBytes > 0) {
device->ungetChar(buf.at(readBytes - 1)); device->ungetChar(buf.at(readBytes - 1));
--readBytes; --readBytes;

View File

@ -41,6 +41,7 @@
#include "qwindowscontext.h" #include "qwindowscontext.h"
#include <QtGui/private/qdnd_p.h> #include <QtGui/private/qdnd_p.h>
#include <QtCore/QByteArrayMatcher>
#include <QtCore/QTextCodec> #include <QtCore/QTextCodec>
#include <QtCore/QMap> #include <QtCore/QMap>
#include <QtCore/QUrl> #include <QtCore/QUrl>
@ -955,9 +956,11 @@ QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pData
QVariant result; QVariant result;
if (canConvertToMime(mime, pDataObj)) { if (canConvertToMime(mime, pDataObj)) {
QByteArray html = getData(CF_HTML, pDataObj); QByteArray html = getData(CF_HTML, pDataObj);
static Q_RELAXED_CONSTEXPR auto startMatcher = qMakeStaticByteArrayMatcher("StartHTML:");
static Q_RELAXED_CONSTEXPR auto endMatcher = qMakeStaticByteArrayMatcher("EndHTML:");
qCDebug(lcQpaMime) << __FUNCTION__ << "raw:" << html; qCDebug(lcQpaMime) << __FUNCTION__ << "raw:" << html;
int start = html.indexOf("StartHTML:"); int start = startMatcher.indexIn(html);
int end = html.indexOf("EndHTML:"); int end = endMatcher.indexIn(html);
if (start != -1) { if (start != -1) {
int startOffset = start + 10; int startOffset = start + 10;
@ -997,10 +1000,13 @@ bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeDa
"StartFragment:0000000000\r\n" // 56-81 "StartFragment:0000000000\r\n" // 56-81
"EndFragment:0000000000\r\n\r\n"; // 82-107 "EndFragment:0000000000\r\n\r\n"; // 82-107
if (data.indexOf("<!--StartFragment-->") == -1) static Q_RELAXED_CONSTEXPR auto startFragmentMatcher = qMakeStaticByteArrayMatcher("<!--StartFragment-->");
static Q_RELAXED_CONSTEXPR auto endFragmentMatcher = qMakeStaticByteArrayMatcher("<!--EndFragment-->");
if (startFragmentMatcher.indexIn(data) == -1)
result += "<!--StartFragment-->"; result += "<!--StartFragment-->";
result += data; result += data;
if (data.indexOf("<!--EndFragment-->") == -1) if (endFragmentMatcher.indexIn(data) == -1)
result += "<!--EndFragment-->"; result += "<!--EndFragment-->";
// set the correct number for EndHTML // set the correct number for EndHTML
@ -1008,9 +1014,9 @@ bool QWindowsMimeHtml::convertFromMime(const FORMATETC &formatetc, const QMimeDa
memcpy(reinterpret_cast<char *>(result.data() + 53 - pos.length()), pos.constData(), size_t(pos.length())); memcpy(reinterpret_cast<char *>(result.data() + 53 - pos.length()), pos.constData(), size_t(pos.length()));
// set correct numbers for StartFragment and EndFragment // set correct numbers for StartFragment and EndFragment
pos = QByteArray::number(result.indexOf("<!--StartFragment-->") + 20); pos = QByteArray::number(startFragmentMatcher.indexIn(result) + 20);
memcpy(reinterpret_cast<char *>(result.data() + 79 - pos.length()), pos.constData(), size_t(pos.length())); memcpy(reinterpret_cast<char *>(result.data() + 79 - pos.length()), pos.constData(), size_t(pos.length()));
pos = QByteArray::number(result.indexOf("<!--EndFragment-->")); pos = QByteArray::number(endFragmentMatcher.indexIn(result));
memcpy(reinterpret_cast<char *>(result.data() + 103 - pos.length()), pos.constData(), size_t(pos.length())); memcpy(reinterpret_cast<char *>(result.data() + 103 - pos.length()), pos.constData(), size_t(pos.length()));
return setData(result, pmedium); return setData(result, pmedium);