From 93ae6f4c06775626db2b2527f7b0c550bf1ea8c4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 19 Oct 2021 10:55:45 +0200 Subject: [PATCH] Fix performance issue in Locator with Qt 6 Locator tries to de-duplicate entries in case results from multiple filters are collected. This is done so we don't get e.g. multiple results for file names, from the various file filters (open documents, project files, included files, ...). For this we define operator== and qHash for LocatorFilterEntry, and add them to a set of "seen" items based on their "internalData" QVariant. For string data that works fine. For non-string data we used qHash for the variant's internal data, and that changed in Qt 6 so we get the same hash a lot of times which hits on the performance big time. Defining qHash generically for QVariant isn't really supported. Since our use case is to de-duplicate items if the internal data is a string, simply restrict our de-duplication to that explicitly. Fixes: QTCREATORBUG-26415 Task-number: QTCREATORBUG-24098 Change-Id: Ifdad17e7e66e9fe4b1300de51c45a5efac73cf3a Reviewed-by: David Schulz --- .../coreplugin/locator/ilocatorfilter.h | 9 ++----- .../coreplugin/locator/locatorsearchutils.cpp | 25 +++++++------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h index bc44cfb1f79..48679878691 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.h +++ b/src/plugins/coreplugin/locator/ilocatorfilter.h @@ -31,9 +31,10 @@ #include #include -#include #include #include +#include +#include namespace Core { @@ -74,12 +75,6 @@ struct LocatorFilterEntry , displayIcon(icon) {} - bool operator==(const LocatorFilterEntry &other) const { - if (internalData.canConvert(QVariant::String)) - return (internalData.toString() == other.internalData.toString()); - return internalData.constData() == other.internalData.constData(); - } - /* backpointer to creating filter */ ILocatorFilter *filter = nullptr; /* displayed string */ diff --git a/src/plugins/coreplugin/locator/locatorsearchutils.cpp b/src/plugins/coreplugin/locator/locatorsearchutils.cpp index a9eb1a7de23..cefe9481c04 100644 --- a/src/plugins/coreplugin/locator/locatorsearchutils.cpp +++ b/src/plugins/coreplugin/locator/locatorsearchutils.cpp @@ -29,21 +29,10 @@ #include #include -namespace Core { - -uint qHash(const LocatorFilterEntry &entry) -{ - if (entry.internalData.canConvert(QVariant::String)) - return QT_PREPEND_NAMESPACE(qHash)(entry.internalData.toString()); - return QT_PREPEND_NAMESPACE(qHash)(entry.internalData.constData()); -} - -} // namespace Core - void Core::Internal::runSearch(QFutureInterface &future, const QList &filters, const QString &searchText) { - QSet alreadyAdded; + QSet alreadyAdded; const bool checkDuplicates = (filters.size() > 1); for (ILocatorFilter *filter : filters) { if (future.isCanceled()) @@ -53,11 +42,15 @@ void Core::Internal::runSearch(QFutureInterface &futur QVector uniqueFilterResults; uniqueFilterResults.reserve(filterResults.size()); for (const LocatorFilterEntry &entry : filterResults) { - if (checkDuplicates && alreadyAdded.contains(entry)) - continue; + if (checkDuplicates) { + const QString stringData = entry.internalData.toString(); + if (!stringData.isEmpty()) { + if (alreadyAdded.contains(stringData)) + continue; + alreadyAdded.insert(stringData); + } + } uniqueFilterResults.append(entry); - if (checkDuplicates) - alreadyAdded.insert(entry); } if (!uniqueFilterResults.isEmpty()) future.reportResults(uniqueFilterResults);