diff options
author | Ivan Komissarov <ABBAPOH@gmail.com> | 2019-05-18 18:21:19 +0200 |
---|---|---|
committer | Ivan Komissarov <ABBAPOH@gmail.com> | 2019-05-22 11:42:56 +0000 |
commit | 9facadbb0e7b6032daac736f5a3084e9ea3c96ba (patch) | |
tree | ba40fdd0f88220ff71f9a2a1e369774b7d2a4956 | |
parent | d5ace749e89a6b6fbf4ec836e054fab21729a0ef (diff) |
Use std:: containers in ProjectBuildData
It appears, that destruction of complex QHashes/QLists took a bit time
in refcounts. Optimize them by using std::unordered_map and std::vector
instead. Plus, make structure simplier, instead of 2 hashes, use pair as
a key.
qbs::Internal::ProjectBuildData::~ProjectBuildData()
Before: 11.00 ms 0.1%
After: 6.00 ms 0.0%
Change-Id: I82d8bec5a465210cfa54762088f47c606c0e48e5
Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | src/lib/corelib/buildgraph/buildgraph.cpp | 9 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/executor.cpp | 5 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/projectbuilddata.cpp | 17 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/projectbuilddata.h | 15 | ||||
-rw-r--r-- | src/lib/corelib/buildgraph/transformerchangetracking.cpp | 3 | ||||
-rw-r--r-- | src/lib/corelib/tools/qttools.h | 10 |
6 files changed, 33 insertions, 26 deletions
diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp index 616658a18..283e8dc2a 100644 --- a/src/lib/corelib/buildgraph/buildgraph.cpp +++ b/src/lib/corelib/buildgraph/buildgraph.cpp @@ -572,13 +572,10 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product, const ProjectBuildData *projectBuildData, const QString &dirPath, const QString &fileName, bool compareByName) { - const QList<FileResourceBase *> lookupResults - = projectBuildData->lookupFiles(dirPath, fileName); - for (QList<FileResourceBase *>::const_iterator it = lookupResults.constBegin(); - it != lookupResults.constEnd(); ++it) { - if ((*it)->fileType() != FileResourceBase::FileTypeArtifact) + for (const auto &fileResource : projectBuildData->lookupFiles(dirPath, fileName)) { + if (fileResource->fileType() != FileResourceBase::FileTypeArtifact) continue; - auto artifact = static_cast<Artifact *>(*it); + const auto artifact = static_cast<Artifact *>(fileResource); if (compareByName ? artifact->product->uniqueName() == product->uniqueName() : artifact->product == product) { diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp index 930c1698e..de81ada20 100644 --- a/src/lib/corelib/buildgraph/executor.cpp +++ b/src/lib/corelib/buildgraph/executor.cpp @@ -243,8 +243,7 @@ void Executor::doBuild() const QStringList &filesToConsider = m_buildOptions.filesToConsider(); if (!filesToConsider.empty()) { for (const QString &fileToConsider : filesToConsider) { - const QList<FileResourceBase *> &files - = m_project->buildData->lookupFiles(fileToConsider); + const auto &files = m_project->buildData->lookupFiles(fileToConsider); for (const FileResourceBase * const file : files) { if (file->fileType() != FileResourceBase::FileTypeArtifact) continue; @@ -838,7 +837,7 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = null childrenToConnect.push_back(child); } for (const QString &depPath : rad.fileDependencies) { - const QList<FileResourceBase *> depList = m_project->buildData->lookupFiles(depPath); + const auto &depList = m_project->buildData->lookupFiles(depPath); if (depList.empty()) { canRescue = false; qCDebug(lcBuildGraph) << "File dependency" << depPath diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index 6a145dacc..31012e23e 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -96,8 +96,7 @@ QString ProjectBuildData::deriveBuildGraphFilePath(const QString &buildDir, cons void ProjectBuildData::insertIntoLookupTable(FileResourceBase *fileres) { - QList<FileResourceBase *> &lst - = m_artifactLookupTable[fileres->fileName()][fileres->dirPath()]; + auto &lst = m_artifactLookupTable[{fileres->fileName(), fileres->dirPath()}]; const auto * const artifact = fileres->fileType() == FileResourceBase::FileTypeArtifact ? static_cast<Artifact *>(fileres) : nullptr; if (artifact && artifact->artifactType == Artifact::Generated) { @@ -117,30 +116,32 @@ void ProjectBuildData::insertIntoLookupTable(FileResourceBase *fileres) throw error; } } - QBS_CHECK(!lst.contains(fileres)); + QBS_CHECK(!contains(lst, fileres)); lst.push_back(fileres); m_isDirty = true; } void ProjectBuildData::removeFromLookupTable(FileResourceBase *fileres) { - m_artifactLookupTable[fileres->fileName()][fileres->dirPath()].removeOne(fileres); + removeOne(m_artifactLookupTable[{fileres->fileName(), fileres->dirPath()}], fileres); } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const QString &filePath) const +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const QString &filePath) const { QString dirPath, fileName; FileInfo::splitIntoDirectoryAndFileName(filePath, &dirPath, &fileName); return lookupFiles(dirPath, fileName); } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const QString &dirPath, +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const QString &dirPath, const QString &fileName) const { - return m_artifactLookupTable.value(fileName).value(dirPath); + static const std::vector<FileResourceBase *> emptyResult; + const auto it = m_artifactLookupTable.find({fileName, dirPath}); + return it != m_artifactLookupTable.end() ? it->second : emptyResult; } -QList<FileResourceBase *> ProjectBuildData::lookupFiles(const Artifact *artifact) const +const std::vector<FileResourceBase *> &ProjectBuildData::lookupFiles(const Artifact *artifact) const { return lookupFiles(artifact->dirPath(), artifact->fileName()); } diff --git a/src/lib/corelib/buildgraph/projectbuilddata.h b/src/lib/corelib/buildgraph/projectbuilddata.h index 49101a716..930344435 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.h +++ b/src/lib/corelib/buildgraph/projectbuilddata.h @@ -45,13 +45,15 @@ #include <logging/logger.h> #include <tools/persistence.h> #include <tools/set.h> +#include <tools/qttools.h> -#include <QtCore/qhash.h> #include <QtCore/qlist.h> #include <QtCore/qstring.h> #include <QtScript/qscriptvalue.h> +#include <unordered_map> + namespace qbs { namespace Internal { class BuildGraphNode; @@ -70,9 +72,9 @@ public: void insertIntoLookupTable(FileResourceBase *fileres); void removeFromLookupTable(FileResourceBase *fileres); - QList<FileResourceBase *> lookupFiles(const QString &filePath) const; - QList<FileResourceBase *> lookupFiles(const QString &dirPath, const QString &fileName) const; - QList<FileResourceBase *> lookupFiles(const Artifact *artifact) const; + const std::vector<FileResourceBase *> &lookupFiles(const QString &filePath) const; + const std::vector<FileResourceBase *> &lookupFiles(const QString &dirPath, const QString &fileName) const; + const std::vector<FileResourceBase *> &lookupFiles(const Artifact *artifact) const; void insertFileDependency(FileDependency *dependency); void removeArtifactAndExclusiveDependents(Artifact *artifact, const Logger &logger, bool removeFromProduct = true, ArtifactSet *removedArtifacts = nullptr); @@ -99,9 +101,10 @@ private: pool.serializationOp<opType>(fileDependencies, rawScanResults); } - using ResultsPerDirectory = QHash<QString, QList<FileResourceBase *>>; - using ArtifactLookupTable = QHash<QString, ResultsPerDirectory>; + using ArtifactKey = std::pair<QString /*fileName*/, QString /*dirName*/>; + using ArtifactLookupTable = std::unordered_map<ArtifactKey, std::vector<FileResourceBase *>>; ArtifactLookupTable m_artifactLookupTable; + bool m_doCleanupInDestructor = true; bool m_isDirty = true; }; diff --git a/src/lib/corelib/buildgraph/transformerchangetracking.cpp b/src/lib/corelib/buildgraph/transformerchangetracking.cpp index eadc99272..505f0cbba 100644 --- a/src/lib/corelib/buildgraph/transformerchangetracking.cpp +++ b/src/lib/corelib/buildgraph/transformerchangetracking.cpp @@ -226,8 +226,7 @@ const Artifact *TrafoChangeTracker::getArtifact(const QString &filePath, const ResolvedProduct * const product = getProduct(productName); if (!product) return nullptr; - const QList<FileResourceBase *> &candidates - = product->topLevelProject()->buildData->lookupFiles(filePath); + const auto &candidates = product->topLevelProject()->buildData->lookupFiles(filePath); const Artifact *artifact = nullptr; for (const FileResourceBase * const candidate : candidates) { if (candidate->fileType() == FileResourceBase::FileTypeArtifact) { diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h index 2252c12d3..4cb39527e 100644 --- a/src/lib/corelib/tools/qttools.h +++ b/src/lib/corelib/tools/qttools.h @@ -53,7 +53,15 @@ namespace std { template<> struct hash<QString> { std::size_t operator()(const QString &s) const { return qHash(s); } }; -} + +template<typename T1, typename T2> struct hash<std::pair<T1, T2>> +{ + size_t operator()(const pair<T1, T2> &x) const + { + return std::hash<T1>()(x.first) ^ std::hash<T2>()(x.second); + } +}; +} // namespace std QT_BEGIN_NAMESPACE uint qHash(const QStringList &list); |