forked from qt-creator/qt-creator
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:
@@ -31,9 +31,10 @@
|
|||||||
#include <utils/id.h>
|
#include <utils/id.h>
|
||||||
#include <utils/optional.h>
|
#include <utils/optional.h>
|
||||||
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
@@ -74,12 +75,6 @@ struct LocatorFilterEntry
|
|||||||
, displayIcon(icon)
|
, 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 */
|
/* backpointer to creating filter */
|
||||||
ILocatorFilter *filter = nullptr;
|
ILocatorFilter *filter = nullptr;
|
||||||
/* displayed string */
|
/* displayed string */
|
||||||
|
@@ -29,21 +29,10 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#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,
|
void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||||
const QList<ILocatorFilter *> &filters, const QString &searchText)
|
const QList<ILocatorFilter *> &filters, const QString &searchText)
|
||||||
{
|
{
|
||||||
QSet<LocatorFilterEntry> alreadyAdded;
|
QSet<QString> alreadyAdded;
|
||||||
const bool checkDuplicates = (filters.size() > 1);
|
const bool checkDuplicates = (filters.size() > 1);
|
||||||
for (ILocatorFilter *filter : filters) {
|
for (ILocatorFilter *filter : filters) {
|
||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
@@ -53,11 +42,15 @@ void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &futur
|
|||||||
QVector<LocatorFilterEntry> uniqueFilterResults;
|
QVector<LocatorFilterEntry> uniqueFilterResults;
|
||||||
uniqueFilterResults.reserve(filterResults.size());
|
uniqueFilterResults.reserve(filterResults.size());
|
||||||
for (const LocatorFilterEntry &entry : filterResults) {
|
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;
|
continue;
|
||||||
|
alreadyAdded.insert(stringData);
|
||||||
|
}
|
||||||
|
}
|
||||||
uniqueFilterResults.append(entry);
|
uniqueFilterResults.append(entry);
|
||||||
if (checkDuplicates)
|
|
||||||
alreadyAdded.insert(entry);
|
|
||||||
}
|
}
|
||||||
if (!uniqueFilterResults.isEmpty())
|
if (!uniqueFilterResults.isEmpty())
|
||||||
future.reportResults(uniqueFilterResults);
|
future.reportResults(uniqueFilterResults);
|
||||||
|
Reference in New Issue
Block a user