diff options
author | Thomas Sondergaard <thomas.sondergaard@karoshealth.com> | 2016-11-01 09:35:31 +0100 |
---|---|---|
committer | Thomas Sondergaard <thomas.sondergaard@karoshealth.com> | 2016-11-03 17:34:57 +0000 |
commit | 4df5003ee7b47a55b2a06b69d57c1a2ca4314607 (patch) | |
tree | d90cd59b16a352424987f5518b0dc92b8c347124 /src/tools/moc | |
parent | 36d3f24d6aebf9d4f56d42eb7702fc40c7406e29 (diff) |
moc: Cache header lookups to reduce number of file stat's
This improves moc performance on Windows where file-stat'ing is slow
and where the number of project include paths to search is often high
because project third-party headers are installed in separate
directories rather than a shared include path such as /usr/include.
In a real project of non-trivial size it reduces the total
from-scratch build time of an optimized build using CMake+ninja with
32 cores by 11% from ~11m35s to ~10m15s.
Change-Id: Ieed59646927ed75c55ed9efa97600c328b2fed2c
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/preprocessor.cpp | 29 | ||||
-rw-r--r-- | src/tools/moc/preprocessor.h | 1 |
2 files changed, 22 insertions, 8 deletions
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 11bf8d7937..f5639ffe31 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -1005,22 +1005,20 @@ static void mergeStringLiterals(Symbols *_symbols) } } -QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo) +static QByteArray searchIncludePaths(const QList<Parser::IncludePath> &includepaths, + const QByteArray &include) { - // #### stringery QFileInfo fi; - if (!relativeTo.isEmpty()) - fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo.constData())).dir(), QString::fromLocal8Bit(include.constData())); - for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { - const IncludePath &p = Preprocessor::includes.at(j); + for (int j = 0; j < includepaths.size() && !fi.exists(); ++j) { + const Parser::IncludePath &p = includepaths.at(j); if (p.isFrameworkPath) { const int slashPos = include.indexOf('/'); if (slashPos == -1) continue; fi.setFile(QString::fromLocal8Bit(p.path + '/' + include.left(slashPos) + ".framework/Headers/"), - QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); + QString::fromLocal8Bit(include.mid(slashPos + 1))); } else { - fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); + fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include)); } // try again, maybe there's a file later in the include paths with the same name // (186067) @@ -1035,6 +1033,21 @@ QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteAr return fi.canonicalFilePath().toLocal8Bit(); } +QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo) +{ + if (!relativeTo.isEmpty()) { + QFileInfo fi; + fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo)).dir(), QString::fromLocal8Bit(include)); + if (fi.exists() && !fi.isDir()) + return fi.canonicalFilePath().toLocal8Bit(); + } + + auto it = nonlocalIncludePathResolutionCache.find(include); + if (it == nonlocalIncludePathResolutionCache.end()) + it = nonlocalIncludePathResolutionCache.insert(include, searchIncludePaths(includes, include)); + return it.value(); +} + void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h index a7eb1a19e1..39f56d6e92 100644 --- a/src/tools/moc/preprocessor.h +++ b/src/tools/moc/preprocessor.h @@ -61,6 +61,7 @@ public: static bool preprocessOnly; QList<QByteArray> frameworks; QSet<QByteArray> preprocessedIncludes; + QHash<QByteArray, QByteArray> nonlocalIncludePathResolutionCache; Macros macros; QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo); Symbols preprocessed(const QByteArray &filename, QFile *device); |