From 6662919ecde901771d9641fd732aa0735ebb39e6 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Thu, 31 Mar 2016 12:01:59 +0300 Subject: CoreLib: use QStringRef to optimize memory allocation Replace substring functions that return QString with corresponding functions that return QStringRef where it's possible. Create QString from QStringRef only where necessary. Change-Id: Id9ea11b16947220cd27787c0b529de62d10b6c26 Reviewed-by: Edward Welbourne --- src/corelib/global/qlibraryinfo.cpp | 2 +- src/corelib/io/qdir.cpp | 8 +++++--- src/corelib/io/qfilesystemengine.cpp | 2 +- src/corelib/io/qfilesystemengine_unix.cpp | 5 +++-- src/corelib/io/qfilesystemengine_win.cpp | 10 ++++++---- src/corelib/io/qfilesystemiterator_win.cpp | 3 ++- src/corelib/io/qresource.cpp | 4 ++-- src/corelib/io/qstandardpaths_unix.cpp | 2 +- src/corelib/io/qurl.cpp | 10 +++++----- src/corelib/kernel/qmetaobject.cpp | 11 ++++++----- src/corelib/kernel/qtranslator.cpp | 2 +- src/corelib/mimetypes/qmimeglobpattern.cpp | 2 +- src/corelib/mimetypes/qmimeprovider.cpp | 5 +++-- src/corelib/mimetypes/qmimetype.cpp | 9 +++++---- src/corelib/plugin/qlibrary.cpp | 8 ++++---- 15 files changed, 46 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index c31b6daa00..4303f74709 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -532,7 +532,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) reg_var.setMinimal(true); while((rep = reg_var.indexIn(ret)) != -1) { ret.replace(rep, reg_var.matchedLength(), - QString::fromLocal8Bit(qgetenv(ret.mid(rep + 2, + QString::fromLocal8Bit(qgetenv(ret.midRef(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData())); } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index af07b52cdb..8197ea63e7 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -146,9 +146,11 @@ inline QStringList QDirPrivate::splitFilters(const QString &nameFilter, QChar se { if (sep.isNull()) sep = getFilterSepChar(nameFilter); - QStringList ret = nameFilter.split(sep); - for (int i = 0; i < ret.count(); ++i) - ret[i] = ret[i].trimmed(); + const QVector split = nameFilter.splitRef(sep); + QStringList ret; + ret.reserve(split.size()); + for (const auto &e : split) + ret.append(e.trimmed().toString()); return ret; } diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index fd8f251ccb..febfdbb9d4 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -91,7 +91,7 @@ QString QFileSystemEngine::slowCanonicalized(const QString &path) if (separatorPos != -1) { if (fi.isDir() && !target.endsWith(slash)) target.append(slash); - target.append(tmpPath.mid(separatorPos)); + target.append(tmpPath.midRef(separatorPos)); } tmpPath = QDir::cleanPath(target); separatorPos = 0; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index eebe5f1f94..6aaaa4c05a 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -182,8 +182,9 @@ QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, #endif if (!ret.startsWith(QLatin1Char('/'))) { - if (link.filePath().startsWith(QLatin1Char('/'))) { - ret.prepend(link.filePath().left(link.filePath().lastIndexOf(QLatin1Char('/'))) + const QString linkFilePath = link.filePath(); + if (linkFilePath.startsWith(QLatin1Char('/'))) { + ret.prepend(linkFilePath.leftRef(linkFilePath.lastIndexOf(QLatin1Char('/'))) + QLatin1Char('/')); } else { ret.prepend(QDir::currentPath() + QLatin1Char('/')); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 8375dc9b1b..abf346a717 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -52,6 +52,7 @@ #include "qvarlengtharray.h" #include "qdatetime.h" #include "qt_windows.h" +#include "qvector.h" #include #include @@ -407,11 +408,11 @@ static QString readLink(const QFileSystemEntry &link) static bool uncShareExists(const QString &server) { // This code assumes the UNC path is always like \\?\UNC\server... - QStringList parts = server.split(QLatin1Char('\\'), QString::SkipEmptyParts); + const QVector parts = server.splitRef(QLatin1Char('\\'), QString::SkipEmptyParts); if (parts.count() >= 3) { QStringList shares; if (QFileSystemEngine::uncListSharesOnServer(QLatin1String("\\\\") + parts.at(2), &shares)) - return parts.count() >= 4 ? shares.contains(parts.at(3), Qt::CaseInsensitive) : true; + return parts.count() < 4 || shares.contains(parts.at(3).toString(), Qt::CaseInsensitive); } return false; } @@ -1106,9 +1107,10 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo if (removeEmptyParents) { dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { - QString chunk = dirName.left(slash); - if (chunk.length() == 2 && chunk.at(0).isLetter() && chunk.at(1) == QLatin1Char(':')) + const QStringRef chunkRef = dirName.leftRef(slash); + if (chunkRef.length() == 2 && chunkRef.at(0).isLetter() && chunkRef.at(1) == QLatin1Char(':')) break; + const QString chunk = chunkRef.toString(); if (!isDirPath(chunk, 0)) return false; if (!rmDir(chunk)) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 9e40a41b4c..2ce7bd7a4b 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -40,6 +40,7 @@ #include "qfilesystemiterator_p.h" #include "qfilesystemengine_p.h" #include "qplatformdefs.h" +#include "qvector.h" #include @@ -103,7 +104,7 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags); if (findFileHandle == INVALID_HANDLE_VALUE) { if (nativePath.startsWith(QLatin1String("\\\\?\\UNC\\"))) { - QStringList parts = nativePath.split(QLatin1Char('\\'), QString::SkipEmptyParts); + const QVector parts = nativePath.splitRef(QLatin1Char('\\'), QString::SkipEmptyParts); if (parts.count() == 4 && QFileSystemEngine::uncListSharesOnServer( QLatin1String("\\\\") + parts.at(2), &uncShares)) { if (uncShares.isEmpty()) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 96957ac11d..7fe3753da4 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -303,12 +303,12 @@ QResourcePrivate::ensureInitialized() const if(!that->absoluteFilePath.startsWith(QLatin1Char(':'))) that->absoluteFilePath.prepend(QLatin1Char(':')); - QString path = fileName; + QStringRef path(&fileName); if(path.startsWith(QLatin1Char(':'))) path = path.mid(1); if(path.startsWith(QLatin1Char('/'))) { - that->load(path); + that->load(path.toString()); } else { QMutexLocker lock(resourceMutex()); QStringList searchPaths = *resourceSearchPaths(); diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index bcbc9664ef..0561e5833f 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -223,7 +223,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (!value.isEmpty()) { // value can start with $HOME if (value.startsWith(QLatin1String("$HOME"))) - value = QDir::homePath() + value.mid(5); + value = QDir::homePath() + value.midRef(5); if (value.length() > 1 && value.endsWith(QLatin1Char('/'))) value.chop(1); return value; diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 40fc492d91..e20a98fbf1 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3784,13 +3784,13 @@ QUrl QUrl::fromLocalFile(const QString &localFile) } else if (deslashified.startsWith(QLatin1String("//"))) { // magic for shared drive on windows int indexOfPath = deslashified.indexOf(QLatin1Char('/'), 2); - QString hostSpec = deslashified.mid(2, indexOfPath - 2); + QStringRef hostSpec = deslashified.midRef(2, indexOfPath - 2); // Check for Windows-specific WebDAV specification: "//host@SSL/path". if (hostSpec.endsWith(webDavSslTag(), Qt::CaseInsensitive)) { - hostSpec.chop(4); + hostSpec.truncate(hostSpec.size() - 4); scheme = webDavScheme(); } - url.setHost(hostSpec); + url.setHost(hostSpec.toString()); if (indexOfPath > 2) deslashified = deslashified.right(deslashified.length() - indexOfPath); @@ -4255,8 +4255,8 @@ QUrl QUrl::fromUserInput(const QString &userInput) if (urlPrepended.isValid() && (!urlPrepended.host().isEmpty() || !urlPrepended.path().isEmpty())) { int dotIndex = trimmedString.indexOf(QLatin1Char('.')); - const QString hostscheme = trimmedString.left(dotIndex).toLower(); - if (hostscheme == ftpScheme()) + const QStringRef hostscheme = trimmedString.leftRef(dotIndex); + if (hostscheme.compare(ftpScheme(), Qt::CaseInsensitive) == 0) urlPrepended.setScheme(ftpScheme()); return adjustFtpPath(urlPrepended); } diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 2f2694f219..f5b879aea8 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2652,15 +2652,16 @@ int QMetaEnum::keysToValue(const char *keys, bool *ok) const return -1; if (ok != 0) *ok = true; - QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|')); - if (l.isEmpty()) + const QString keysString = QString::fromLatin1(keys); + const QVector splitKeys = keysString.splitRef(QLatin1Char('|')); + if (splitKeys.isEmpty()) return 0; - //#### TODO write proper code, do not use QStringList + // ### TODO write proper code: do not allocate memory, so we can go nothrow int value = 0; int count = mobj->d.data[handle + 2]; int data = mobj->d.data[handle + 3]; - for (int li = 0; li < l.size(); ++li) { - QString trimmed = l.at(li).trimmed(); + for (const QStringRef &untrimmed : splitKeys) { + const QStringRef trimmed = untrimmed.trimmed(); QByteArray qualified_key = trimmed.toLatin1(); const char *key = qualified_key.constData(); uint scope = 0; diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 2c813b5156..e016773bde 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -487,7 +487,7 @@ bool QTranslator::load(const QString & filename, const QString & directory, } const QString suffixOrDotQM = suffix.isNull() ? dotQmLiteral() : suffix; - QString fname = filename; + QStringRef fname(&filename); QString realname; QString delims; delims = search_delimiters.isNull() ? QStringLiteral("_.") : search_delimiters; diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp index 94be5385f3..568f9bf4de 100644 --- a/src/corelib/mimetypes/qmimeglobpattern.cpp +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -124,7 +124,7 @@ bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) { if (len + 1 < pattern_len) return false; if (m_pattern.at(0) == QLatin1Char('*')) - return filename.indexOf(m_pattern.mid(1, pattern_len - 2)) != -1; + return filename.indexOf(m_pattern.midRef(1, pattern_len - 2)) != -1; const QChar *c1 = m_pattern.unicode(); const QChar *c2 = filename.unicode(); diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index dc6eb05d9a..e72f9a30d0 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE static QString fallbackParent(const QString &mimeTypeName) { - const QString myGroup = mimeTypeName.left(mimeTypeName.indexOf(QLatin1Char('/'))); + const QStringRef myGroup = mimeTypeName.leftRef(mimeTypeName.indexOf(QLatin1Char('/'))); // All text/* types are subclasses of text/plain. if (myGroup == QLatin1String("text") && mimeTypeName != QLatin1String("text/plain")) return QLatin1String("text/plain"); @@ -363,7 +363,8 @@ bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBin const int weight = flagsAndWeight & 0xff; const bool caseSensitive = flagsAndWeight & 0x100; if (caseSensitiveCheck || !caseSensitive) { - result.addMatch(QLatin1String(mimeType), weight, QLatin1Char('*') + fileName.mid(charPos+1)); + result.addMatch(QLatin1String(mimeType), weight, + QLatin1Char('*') + fileName.midRef(charPos + 1)); success = true; } } diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index 80b6a76ecc..5d18b67e8d 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -286,11 +286,12 @@ QString QMimeType::genericIconName() const // then the mimetype is used to generate the generic icon by using the top-level // media type (e.g. "video" in "video/ogg") and appending "-x-generic" // (i.e. "video-x-generic" in the previous example). - QString group = name(); - const int slashindex = group.indexOf(QLatin1Char('/')); + const QString group = name(); + QStringRef groupRef(&group); + const int slashindex = groupRef.indexOf(QLatin1Char('/')); if (slashindex != -1) - group = group.left(slashindex); - return group + QLatin1String("-x-generic"); + groupRef = groupRef.left(slashindex); + return groupRef + QLatin1String("-x-generic"); } return d->genericIconName; } diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index f7e57461e3..886dd20d0e 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -616,12 +616,12 @@ bool QLibrary::isLibrary(const QString &fileName) QString completeSuffix = QFileInfo(fileName).completeSuffix(); if (completeSuffix.isEmpty()) return false; - QStringList suffixes = completeSuffix.split(QLatin1Char('.')); + const QVector suffixes = completeSuffix.splitRef(QLatin1Char('.')); # if defined(Q_OS_DARWIN) // On Mac, libs look like libmylib.1.0.0.dylib - const QString lastSuffix = suffixes.at(suffixes.count() - 1); - const QString firstSuffix = suffixes.at(0); + const QStringRef &lastSuffix = suffixes.at(suffixes.count() - 1); + const QStringRef &firstSuffix = suffixes.at(0); bool valid = (lastSuffix == QLatin1String("dylib") || firstSuffix == QLatin1String("so") @@ -657,7 +657,7 @@ bool QLibrary::isLibrary(const QString &fileName) int suffix; int suffixPos = -1; for (suffix = 0; suffix < validSuffixList.count() && suffixPos == -1; ++suffix) - suffixPos = suffixes.indexOf(validSuffixList.at(suffix)); + suffixPos = suffixes.indexOf(QStringRef(&validSuffixList.at(suffix))); bool valid = suffixPos != -1; for (int i = suffixPos + 1; i < suffixes.count() && valid; ++i) -- cgit v1.2.3