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 <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2021-10-19 10:55:45 +02:00
parent 755932eca7
commit 93ae6f4c06
2 changed files with 11 additions and 23 deletions

View File

@@ -31,9 +31,10 @@
#include <utils/id.h>
#include <utils/optional.h>
#include <QVariant>
#include <QFutureInterface>
#include <QIcon>
#include <QMetaType>
#include <QVariant>
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 */

View File

@@ -29,21 +29,10 @@
#include <QString>
#include <QVariant>
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<Core::LocatorFilterEntry> &future,
const QList<ILocatorFilter *> &filters, const QString &searchText)
{
QSet<LocatorFilterEntry> alreadyAdded;
QSet<QString> alreadyAdded;
const bool checkDuplicates = (filters.size() > 1);
for (ILocatorFilter *filter : filters) {
if (future.isCanceled())
@@ -53,11 +42,15 @@ void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &futur
QVector<LocatorFilterEntry> uniqueFilterResults;
uniqueFilterResults.reserve(filterResults.size());
for (const LocatorFilterEntry &entry : filterResults) {
if (checkDuplicates && alreadyAdded.contains(entry))
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);