aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Komissarov <ABBAPOH@gmail.com>2019-05-18 18:21:19 +0200
committerIvan Komissarov <ABBAPOH@gmail.com>2019-05-22 11:42:56 +0000
commit9facadbb0e7b6032daac736f5a3084e9ea3c96ba (patch)
treeba40fdd0f88220ff71f9a2a1e369774b7d2a4956
parentd5ace749e89a6b6fbf4ec836e054fab21729a0ef (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.cpp9
-rw-r--r--src/lib/corelib/buildgraph/executor.cpp5
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp17
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.h15
-rw-r--r--src/lib/corelib/buildgraph/transformerchangetracking.cpp3
-rw-r--r--src/lib/corelib/tools/qttools.h10
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);