diff options
author | Aleix Pol <aleixpol@kde.org> | 2021-07-01 02:50:55 +0200 |
---|---|---|
committer | Aleix Pol <aleixpol@kde.org> | 2021-07-04 17:22:45 +0200 |
commit | 93c9398cdcf147c5c5e1a89662ffd047e36927ac (patch) | |
tree | 52b09ee245368e799a2c1b60028fd2d99f484adb /src | |
parent | 74a861c5617621663b1d5d8a1cd79c7a0eef9d8a (diff) | |
download | kconfig-93c9398cdcf147c5c5e1a89662ffd047e36927ac.tar.gz kconfig-93c9398cdcf147c5c5e1a89662ffd047e36927ac.tar.bz2 |
Cache global config files
Whenever we read a config file, we are first parsing kdeglobalsrc. This
caches the parsed entries so that they can be reused as long as it
hasn't changed.
This reduces the parseConfig calls (which is mostly prominent at
early process startup) from 18 to 12 (33%) ksmserver-logout-greeter.
This also means there's better cache locality as well as less memory
allocated as a lot of objects are shared but I have not measured this.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/kconfig.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp index cc3700e1..9b8d2e62 100644 --- a/src/core/kconfig.cpp +++ b/src/core/kconfig.cpp @@ -21,6 +21,7 @@ #include <QBasicMutex> #include <QByteArray> +#include <QCache> #include <QCoreApplication> #include <QDir> #include <QFile> @@ -28,6 +29,7 @@ #include <QMutexLocker> #include <QProcess> #include <QSet> +#include <QThreadStorage> #if KCONFIG_USE_DBUS #include <QDBusConnection> @@ -44,6 +46,14 @@ Q_GLOBAL_STATIC(QStringList, s_globalFiles) // For caching purposes. static QBasicMutex s_globalFilesMutex; Q_GLOBAL_STATIC_WITH_ARGS(QString, sGlobalFileName, (QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/kdeglobals"))) +using ParseCacheKey = std::pair<QStringList, QString>; +struct ParseCacheValue { + KEntryMap entries; + QDateTime parseTime; +}; +using ParseCache = QThreadStorage<QCache<ParseCacheKey, ParseCacheValue>>; +Q_GLOBAL_STATIC(ParseCache, sGlobalParse) + #ifndef Q_OS_WIN static const Qt::CaseSensitivity sPathCaseSensitivity = Qt::CaseSensitive; #else @@ -687,8 +697,25 @@ void KConfigPrivate::parseGlobalFiles() const QStringList globalFiles = getGlobalFiles(); // qDebug() << "parsing global files" << globalFiles; - // TODO: can we cache the values in etc_kderc / other global files - // on a per-application basis? + Q_ASSERT(entryMap.isEmpty()); + const ParseCacheKey key = {globalFiles, locale}; + auto data = sGlobalParse->localData().object(key); + QDateTime newest; + for (const auto &file : globalFiles) { + const auto fileDate = QFileInfo(file).lastModified(); + if (fileDate > newest) { + newest = fileDate; + } + } + if (data) { + if (data->parseTime < newest) { + data = nullptr; + } else { + entryMap = data->entries; + return; + } + } + const QByteArray utf8Locale = locale.toUtf8(); for (const QString &file : globalFiles) { KConfigBackend::ParseOptions parseOpts = KConfigBackend::ParseGlobal | KConfigBackend::ParseExpansions; @@ -701,6 +728,7 @@ void KConfigPrivate::parseGlobalFiles() break; } } + sGlobalParse->localData().insert(key, new ParseCacheValue({entryMap, newest})); } void KConfigPrivate::parseConfigFiles() |