ClassView: Optimize operator== of internal data

Make all of the fields of SymbolLocation and SymbolInformation
const members. Optimize a bit operator== of these structures:
check first if hashes are non-equal - in this case return
false early. Fix hash type of SymbolInformation for porting
to Qt6 purpose.

Task-number: QTCREATORBUG-25317
Task-number: QTCREATORBUG-24098
Change-Id: I769f99ff3157093e9f10ee3929bc7f6eb83f34e3
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2021-02-16 01:37:49 +01:00
parent 06f305265b
commit 4a15f6d16b
6 changed files with 38 additions and 37 deletions

View File

@@ -317,8 +317,7 @@ void Manager::gotoLocations(const QList<QVariant> &list)
return; return;
// Default to first known location // Default to first known location
SymbolLocation loc = *locations.constBegin(); auto locationIt = locations.constBegin();
if (locations.size() > 1) { if (locations.size() > 1) {
// The symbol has multiple locations. Check if we are already at one location, // The symbol has multiple locations. Check if we are already at one location,
// and if so, cycle to the "next" one // and if so, cycle to the "next" one
@@ -329,20 +328,19 @@ void Manager::gotoLocations(const QList<QVariant> &list)
int line; int line;
int column; int column;
textEditor->convertPosition(textEditor->position(), &line, &column); textEditor->convertPosition(textEditor->position(), &line, &column);
SymbolLocation current(fileName, line, column); const SymbolLocation current(fileName, line, column);
QSet<SymbolLocation>::const_iterator it = locations.constFind(current); if (auto it = locations.constFind(current), end = locations.constEnd(); it != end) {
QSet<SymbolLocation>::const_iterator end = locations.constEnd();
if (it != end) {
// we already are at the symbol, cycle to next location // we already are at the symbol, cycle to next location
++it; ++it;
if (it == end) if (it == end)
it = locations.constBegin(); it = locations.constBegin();
loc = *it; locationIt = it;
} }
} }
} }
const SymbolLocation &location = *locationIt;
// line is 1-based, column is 0-based // line is 1-based, column is 0-based
gotoLocation(loc.fileName(), loc.line(), loc.column() - 1); gotoLocation(location.fileName(), location.line(), location.column() - 1);
} }
/*! /*!

View File

@@ -479,6 +479,7 @@ void Parser::requestCurrentState()
{ {
d->timer.stop(); d->timer.stop();
// TODO: we need to have a fresh SessionManager data here, which we could pass to parse()
const ParserTreeItem::ConstPtr newRoot = parse(); const ParserTreeItem::ConstPtr newRoot = parse();
{ {
QWriteLocker locker(&d->rootItemLocker); QWriteLocker locker(&d->rootItemLocker);

View File

@@ -49,13 +49,16 @@ SymbolInformation::SymbolInformation() :
} }
SymbolInformation::SymbolInformation(const QString &valueName, const QString &valueType, SymbolInformation::SymbolInformation(const QString &valueName, const QString &valueType,
int valueIconType) : int valueIconType)
m_iconType(valueIconType), : m_iconType(valueIconType)
m_name(valueName), #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_type(valueType) , m_hash(qHashMulti(0, valueIconType, valueName, valueType))
#else
, m_hash(qHash(qMakePair(valueIconType, qMakePair(valueName, valueType))))
#endif
, m_name(valueName)
, m_type(valueType)
{ {
// calculate hash
m_hash = qHash(qMakePair(m_iconType, qMakePair(m_name, m_type)));
} }
/*! /*!
@@ -94,7 +97,8 @@ int SymbolInformation::iconTypeSortOrder() const
static QHash<int, int> sortOrder; static QHash<int, int> sortOrder;
// initialization // TODO: Check if this static initialization is OK when SymbolInformation object are
// instantiated in different threads.
if (sortOrder.isEmpty()) { if (sortOrder.isEmpty()) {
for (int i : IconSortOrder) for (int i : IconSortOrder)
sortOrder.insert(i, sortOrder.count()); sortOrder.insert(i, sortOrder.count());

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include <utils/porting.h>
#include <QMetaType> #include <QMetaType>
#include <QString> #include <QString>
@@ -47,17 +49,17 @@ public:
inline uint hash() const { return m_hash; } inline uint hash() const { return m_hash; }
inline bool operator==(const SymbolInformation &other) const inline bool operator==(const SymbolInformation &other) const
{ {
return iconType() == other.iconType() && name() == other.name() return hash() == other.hash() && iconType() == other.iconType() && name() == other.name()
&& type() == other.type(); && type() == other.type();
} }
int iconTypeSortOrder() const; int iconTypeSortOrder() const;
private: private:
int m_iconType; //!< icon type const int m_iconType;
uint m_hash; //!< precalculated hash value - to speed up qHash const Utils::QHashValueType m_hash; // precalculated hash value - to speed up qHash
QString m_name; //!< symbol name (e.g. SymbolInformation) const QString m_name; // symbol name (e.g. SymbolInformation)
QString m_type; //!< symbol type (e.g. (int char)) const QString m_type; // symbol type (e.g. (int char))
}; };

View File

@@ -45,20 +45,16 @@ SymbolLocation::SymbolLocation() :
{ {
} }
SymbolLocation::SymbolLocation(QString file, int lineNumber, int columnNumber) : SymbolLocation::SymbolLocation(const QString &file, int lineNumber, int columnNumber)
m_fileName(file), : m_fileName(file)
m_line(lineNumber), , m_line(lineNumber)
m_column(columnNumber) , m_column(qMax(columnNumber, 0))
{
if (m_column < 0)
m_column = 0;
// pre-computate hash value
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_hash = qHashMulti(0, m_fileName, m_line, m_column); , m_hash(qHashMulti(0, m_fileName, m_line, m_column))
#else #else
m_hash = qHash(qMakePair(m_fileName, qMakePair(m_line, m_column))); , m_hash(qHash(qMakePair(m_fileName, qMakePair(m_line, m_column))))
#endif #endif
{
} }
} // namespace Internal } // namespace Internal

View File

@@ -40,7 +40,7 @@ public:
SymbolLocation(); SymbolLocation();
//! Constructor //! Constructor
explicit SymbolLocation(QString file, int lineNumber = 0, int columnNumber = 0); explicit SymbolLocation(const QString &file, int lineNumber = 0, int columnNumber = 0);
inline const QString &fileName() const { return m_fileName; } inline const QString &fileName() const { return m_fileName; }
inline int line() const { return m_line; } inline int line() const { return m_line; }
@@ -48,15 +48,15 @@ public:
inline Utils::QHashValueType hash() const { return m_hash; } inline Utils::QHashValueType hash() const { return m_hash; }
inline bool operator==(const SymbolLocation &other) const inline bool operator==(const SymbolLocation &other) const
{ {
return line() == other.line() && column() == other.column() return hash() == other.hash() && line() == other.line() && column() == other.column()
&& fileName() == other.fileName(); && fileName() == other.fileName();
} }
private: private:
QString m_fileName; //!< file name const QString m_fileName;
int m_line; //!< line number const int m_line;
int m_column; //!< column const int m_column;
Utils::QHashValueType m_hash; //!< precalculated hash value for the object, to speed up qHash const Utils::QHashValueType m_hash; // precalculated hash value - to speed up qHash
}; };
//! qHash overload for QHash/QSet //! qHash overload for QHash/QSet