Optimize equality operators for string classes
Using compare() for those operators is not a good idea, as we can't shortcut comparisons if the string sizes are different. This alone made our HTML parser in QtGui around 15% slower. Don't go through QAnyStringView to implement compare() for QUtf8StringView, use QtPrivate::compareStrings() directly instead. Task-number: QTBUG-86354 Change-Id: I04869c29c9918161990dc1baf8e943b3a264ff3c Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
This commit is contained in:
parent
3807559d37
commit
8a7b74f6e7
@ -200,6 +200,7 @@ public:
|
|||||||
[[nodiscard]] constexpr const void *data() const noexcept { return m_data; }
|
[[nodiscard]] constexpr const void *data() const noexcept { return m_data; }
|
||||||
|
|
||||||
[[nodiscard]] Q_CORE_EXPORT static int compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT static int compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT static bool equal(QAnyStringView lhs, QAnyStringView rhs) noexcept;
|
||||||
|
|
||||||
//
|
//
|
||||||
// STL compatibility API:
|
// STL compatibility API:
|
||||||
@ -224,9 +225,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] friend inline bool operator==(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
[[nodiscard]] friend inline bool operator==(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
||||||
{ return QAnyStringView::compare(lhs, rhs) == 0; }
|
{ return QAnyStringView::equal(lhs, rhs); }
|
||||||
[[nodiscard]] friend inline bool operator!=(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
[[nodiscard]] friend inline bool operator!=(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
||||||
{ return !operator==(lhs, rhs); }
|
{ return !QAnyStringView::equal(lhs, rhs); }
|
||||||
|
|
||||||
#ifdef __cpp_impl_three_way_comparison
|
#ifdef __cpp_impl_three_way_comparison
|
||||||
[[nodiscard]] friend inline auto operator<=>(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
[[nodiscard]] friend inline auto operator<=>(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
||||||
|
@ -1325,6 +1325,63 @@ int QAnyStringView::compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSens
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QStringView lhs, QStringView rhs) noexcept
|
||||||
|
{
|
||||||
|
return ucstrcmp(lhs.begin(), lhs.size(), rhs.begin(), rhs.size()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QStringView lhs, QLatin1String rhs) noexcept
|
||||||
|
{
|
||||||
|
return ucstrcmp(lhs.begin(), lhs.size(), rhs.begin(), rhs.size()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QLatin1String lhs, QStringView rhs) noexcept
|
||||||
|
{
|
||||||
|
return QtPrivate::equalStrings(rhs, lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QLatin1String lhs, QLatin1String rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.size() == rhs.size() && (!lhs.size() || qstrncmp(lhs.data(), rhs.data(), lhs.size()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QBasicUtf8StringView<false> lhs, QStringView rhs) noexcept
|
||||||
|
{
|
||||||
|
return QUtf8::compareUtf8(lhs, rhs) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QStringView lhs, QBasicUtf8StringView<false> rhs) noexcept
|
||||||
|
{
|
||||||
|
return QtPrivate::equalStrings(rhs, lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QLatin1String lhs, QBasicUtf8StringView<false> rhs) noexcept
|
||||||
|
{
|
||||||
|
QString r = rhs.toString();
|
||||||
|
return QtPrivate::equalStrings(lhs, r); // ### optimize!
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QBasicUtf8StringView<false> lhs, QLatin1String rhs) noexcept
|
||||||
|
{
|
||||||
|
return QtPrivate::equalStrings(rhs, lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtPrivate::equalStrings(QBasicUtf8StringView<false> lhs, QBasicUtf8StringView<false> rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.size() == rhs.size() && (!lhs.size() || qstrncmp(lhs.data(), rhs.data(), lhs.size()) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QAnyStringView::equal(QAnyStringView lhs, QAnyStringView rhs) noexcept
|
||||||
|
{
|
||||||
|
if (lhs.size() != rhs.size() && lhs.isUtf8() == rhs.isUtf8())
|
||||||
|
return false;
|
||||||
|
return lhs.visit([rhs](auto lhs) {
|
||||||
|
return rhs.visit([lhs](auto rhs) {
|
||||||
|
return QtPrivate::equalStrings(lhs, rhs);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\relates QStringView
|
\relates QStringView
|
||||||
\internal
|
\internal
|
||||||
|
@ -1042,11 +1042,6 @@ QString QBasicUtf8StringView<UseChar8T>::toString() const
|
|||||||
return QString::fromUtf8(data(), int(size()));
|
return QString::fromUtf8(data(), int(size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool UseChar8T>
|
|
||||||
inline int QBasicUtf8StringView<UseChar8T>::compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs,
|
|
||||||
Qt::CaseSensitivity cs) noexcept
|
|
||||||
{ return QAnyStringView::compare(lhs, rhs, cs); }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// QAnyStringView inline members that require QString:
|
// QAnyStringView inline members that require QString:
|
||||||
//
|
//
|
||||||
@ -1444,7 +1439,7 @@ inline bool operator<=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs <
|
|||||||
inline bool operator>=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs > lhs); }
|
inline bool operator>=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs > lhs); }
|
||||||
|
|
||||||
// QStringView <> QStringView
|
// QStringView <> QStringView
|
||||||
inline bool operator==(QStringView lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
|
inline bool operator==(QStringView lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::equalStrings(lhs, rhs); }
|
||||||
inline bool operator!=(QStringView lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
|
inline bool operator!=(QStringView lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
|
||||||
inline bool operator< (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
inline bool operator< (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
||||||
inline bool operator<=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
inline bool operator<=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
||||||
@ -1467,14 +1462,14 @@ inline bool operator> (QChar lhs, QStringView rhs) noexcept { return QStringView
|
|||||||
inline bool operator>=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) >= rhs; }
|
inline bool operator>=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) >= rhs; }
|
||||||
|
|
||||||
// QStringView <> QLatin1String
|
// QStringView <> QLatin1String
|
||||||
inline bool operator==(QStringView lhs, QLatin1String rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
|
inline bool operator==(QStringView lhs, QLatin1String rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::equalStrings(lhs, rhs); }
|
||||||
inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
|
inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
|
||||||
inline bool operator< (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
inline bool operator< (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
||||||
inline bool operator<=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
inline bool operator<=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
||||||
inline bool operator> (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
|
inline bool operator> (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
|
||||||
inline bool operator>=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
|
inline bool operator>=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
|
||||||
|
|
||||||
inline bool operator==(QLatin1String lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
|
inline bool operator==(QLatin1String lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::equalStrings(lhs, rhs); }
|
||||||
inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
|
inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
|
||||||
inline bool operator< (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
inline bool operator< (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
|
||||||
inline bool operator<=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
inline bool operator<=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
|
||||||
|
@ -86,6 +86,16 @@ namespace QtPrivate {
|
|||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QBasicUtf8StringView<false> lhs, QLatin1String rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QBasicUtf8StringView<false> lhs, QLatin1String rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QBasicUtf8StringView<false> lhs, QBasicUtf8StringView<false> rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QBasicUtf8StringView<false> lhs, QBasicUtf8StringView<false> rhs, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QStringView lhs, QStringView rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QStringView lhs, QLatin1String rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QStringView lhs, QBasicUtf8StringView<false> rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QLatin1String lhs, QStringView rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QLatin1String lhs, QLatin1String rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QLatin1String lhs, QBasicUtf8StringView<false> rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QBasicUtf8StringView<false> lhs, QStringView rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QBasicUtf8StringView<false> lhs, QLatin1String rhs) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool equalStrings(QBasicUtf8StringView<false> lhs, QBasicUtf8StringView<false> rhs) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QLatin1String haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QLatin1String haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
|
@ -306,11 +306,17 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] static inline int compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs,
|
[[nodiscard]] static inline int compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
|
||||||
Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
{
|
||||||
|
return QtPrivate::compareStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
|
||||||
|
QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] friend inline bool operator==(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
|
[[nodiscard]] friend inline bool operator==(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
|
||||||
{ return QBasicUtf8StringView::compare(lhs, rhs) == 0; }
|
{
|
||||||
|
return QtPrivate::equalStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
|
||||||
|
QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
|
||||||
|
}
|
||||||
[[nodiscard]] friend inline bool operator!=(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
|
[[nodiscard]] friend inline bool operator!=(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
|
||||||
{ return !operator==(lhs, rhs); }
|
{ return !operator==(lhs, rhs); }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user