From 9facadbb0e7b6032daac736f5a3084e9ea3c96ba Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 18 May 2019 18:21:19 +0200 Subject: 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 Reviewed-by: Christian Kandeler --- src/lib/corelib/buildgraph/buildgraph.cpp | 9 +++------ src/lib/corelib/buildgraph/executor.cpp | 5 ++--- src/lib/corelib/buildgraph/projectbuilddata.cpp | 17 +++++++++-------- src/lib/corelib/buildgraph/projectbuilddata.h | 15 +++++++++------ .../corelib/buildgraph/transformerchangetracking.cpp | 3 +-- src/lib/corelib/tools/qttools.h | 10 +++++++++- 6 files changed, 33 insertions(+), 26 deletions(-) (limited to 'src') 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 lookupResults - = projectBuildData->lookupFiles(dirPath, fileName); - for (QList::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(*it); + const auto artifact = static_cast(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 &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 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 &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(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 ProjectBuildData::lookupFiles(const QString &filePath) const +const std::vector &ProjectBuildData::lookupFiles(const QString &filePath) const { QString dirPath, fileName; FileInfo::splitIntoDirectoryAndFileName(filePath, &dirPath, &fileName); return lookupFiles(dirPath, fileName); } -QList ProjectBuildData::lookupFiles(const QString &dirPath, +const std::vector &ProjectBuildData::lookupFiles(const QString &dirPath, const QString &fileName) const { - return m_artifactLookupTable.value(fileName).value(dirPath); + static const std::vector emptyResult; + const auto it = m_artifactLookupTable.find({fileName, dirPath}); + return it != m_artifactLookupTable.end() ? it->second : emptyResult; } -QList ProjectBuildData::lookupFiles(const Artifact *artifact) const +const std::vector &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 #include #include +#include -#include #include #include #include +#include + namespace qbs { namespace Internal { class BuildGraphNode; @@ -70,9 +72,9 @@ public: void insertIntoLookupTable(FileResourceBase *fileres); void removeFromLookupTable(FileResourceBase *fileres); - QList lookupFiles(const QString &filePath) const; - QList lookupFiles(const QString &dirPath, const QString &fileName) const; - QList lookupFiles(const Artifact *artifact) const; + const std::vector &lookupFiles(const QString &filePath) const; + const std::vector &lookupFiles(const QString &dirPath, const QString &fileName) const; + const std::vector &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(fileDependencies, rawScanResults); } - using ResultsPerDirectory = QHash>; - using ArtifactLookupTable = QHash; + using ArtifactKey = std::pair; + using ArtifactLookupTable = std::unordered_map>; 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 &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 { std::size_t operator()(const QString &s) const { return qHash(s); } }; -} + +template struct hash> +{ + size_t operator()(const pair &x) const + { + return std::hash()(x.first) ^ std::hash()(x.second); + } +}; +} // namespace std QT_BEGIN_NAMESPACE uint qHash(const QStringList &list); -- cgit v1.2.3