From 9a5d6523689067a9cde717a8f375d4eca246b119 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Wed, 18 Jun 2014 13:57:35 +0200 Subject: Optimize KConfigGroup::exists and similar operations. Before, these kind of read-only operations did a lot of allocations: 1) allocate a list of all sub groups 2) for the above, also allocate a sub-group match key 3) iterate over sub groups, allocate a list of all keys in there and then finally check whether that list is non-empty All of the above is now done without a single allocation, by simply iterating over the list of entries. Note: The whole list was iterated even before in allSubGroups. Now we still do that, but check for non-empty keys in the group or sub group directly. Much more efficient. Note2: While at it, allSubGroups is also optimized to not require the allocation of the subgroup match key. REVIEW: 118586 forward-port of commit eaffd50adfd7fcbeafadb0248904176808b4499d --- src/core/kconfig.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp index 65edefa9..b9319994 100644 --- a/src/core/kconfig.cpp +++ b/src/core/kconfig.cpp @@ -302,16 +302,22 @@ QStringList KConfigPrivate::groupList(const QByteArray &group) const return groups.toList(); } +static bool isGroupOrSubGroupMatch(const QByteArray &potentialGroup, const QByteArray &group) +{ + if (!potentialGroup.startsWith(group)) { + return false; + } + return potentialGroup.length() == group.length() || potentialGroup[group.length()] == '\x1d'; +} + // List all sub groups, including subsubgroups QSet KConfigPrivate::allSubGroups(const QByteArray &parentGroup) const { QSet groups; - QByteArray theGroup = parentGroup + '\x1d'; - groups << parentGroup; for (KEntryMap::const_iterator entryMapIt = entryMap.begin(); entryMapIt != entryMap.end(); ++entryMapIt) { const KEntryKey &key = entryMapIt.key(); - if (key.mKey.isNull() && key.mGroup.startsWith(theGroup)) { + if (key.mKey.isNull() && isGroupOrSubGroupMatch(key.mGroup, parentGroup)) { groups << key.mGroup; } } @@ -320,12 +326,10 @@ QSet KConfigPrivate::allSubGroups(const QByteArray &parentGroup) con bool KConfigPrivate::hasNonDeletedEntries(const QByteArray &group) const { - const QSet allGroups = allSubGroups(group); - - Q_FOREACH (const QByteArray &aGroup, allGroups) { - // Could be optimized, let's use the slow way for now + for (KEntryMap::const_iterator it = entryMap.begin(); it != entryMap.end(); ++it) { + const KEntryKey &key = it.key(); // Check for any non-deleted entry - if (!keyListImpl(aGroup).isEmpty()) { + if (isGroupOrSubGroupMatch(key.mGroup, group) && !key.mKey.isNull() && !it->bDeleted) { return true; } } -- cgit v1.2.1