QMetaType: make sequence, pair adapters SCARY

Extract (non-template) Methods from template functions and pull them
behind the ABI boundary to avoid re-compiling the same code multiple
times ("SCARY").

In this particular case, the extracted code contains
QMetaType::fromType() calls, which, taken together, were responsible
for at least 91s of the ~8250s total time for a qt5.git-wide
headersclean_check (1.1%):

Says Clang -ftime-trace:

  $ grep fromType hc*.txt
  hc-00-baseline.txt: 32122 ms: QMetaType::fromType<QIterable<QMetaAssociation>> (1240 times, avg 25 ms)
  hc-00-baseline.txt: 31717 ms: QMetaType::fromType<QIterable<QMetaSequence>> (1240 times, avg 25 ms)
  hc-00-baseline.txt: 23531 ms: QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl> (1240 times, avg 18 ms)
  hc-00-baseline.txt: 91143 ms: QMetaType::fromType<$> (6440 times, avg 14 ms)
  # QIterable<QMetaSequence> out-of-lined:
  hc-01-meta-seq.txt: 29869 ms: QMetaType::fromType<QIterable<QMetaAssociation>> (1240 times, avg 24 ms)
  hc-01-meta-seq.txt: 21618 ms: QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl> (1240 times, avg 17 ms)
  hc-01-meta-seq.txt: 55029 ms: QMetaType::fromType<$> (5025 times, avg 10 ms)
  # QIterable<QMetaAssociation> out-of-lined:
  hc-02-meta-ass.txt: 21689 ms: QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl> (1240 times, avg 17 ms)
  hc-02-meta-ass.txt: 25224 ms: QMetaType::fromType<$> (3799 times, avg 6 ms)
  # QPairVariantInterfaceImpl out-of-lined:
  <crickets>

Amends 01fb843af88d949cd38b494a60bb64b730a045d2 (sequences),
87e27eb870d08ee8953cc9b350ed29c5b3e4f785 (associations),
b88b09fb16754c5057b781d1b625855f75b22aee (pairs).

Task-number: QTBUG-97601
Change-Id: If34cf94703a203bc231f1bac656d2f5278bbd8f8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Marc Mutz 2024-05-03 11:24:09 +02:00
parent bf96c45f94
commit d31054c314
2 changed files with 64 additions and 10 deletions

View File

@ -2659,6 +2659,36 @@ bool QMetaType::hasRegisteredConverterFunction(QMetaType fromType, QMetaType toT
return customTypesConversionRegistry()->contains({fromType.id(), toType.id()});
}
/*!
\internal
Non-template helper ("SCARY") for IsMetaTypePair::registerConverter().
*/
bool QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m)
{
const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
return QMetaType::hasRegisteredConverterFunction(m, to);
}
/*!
\internal
Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerConverter().
*/
bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m)
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
return QMetaType::hasRegisteredConverterFunction(m, to);
}
/*!
\internal
Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerConverter().
*/
bool QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m)
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
return QMetaType::hasRegisteredConverterFunction(m, to);
}
/*!
\fn template<typename From, typename To> bool QMetaType::hasRegisteredMutableViewFunction()
Returns \c true, if the meta type system has a registered mutable view on type From of type To.
@ -2676,6 +2706,26 @@ bool QMetaType::hasRegisteredMutableViewFunction(QMetaType fromType, QMetaType t
return customTypesMutableViewRegistry()->contains({fromType.id(), toType.id()});
}
/*!
\internal
Non-template helper ("SCARY") for SequentialValueTypeIsMetaType::registerMutableView().
*/
bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m)
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
return QMetaType::hasRegisteredMutableViewFunction(m, to);
}
/*!
\internal
Non-template helper ("SCARY") for AssociativeKeyTypeIsMetaType::registerMutableView().
*/
bool QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m)
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
return QMetaType::hasRegisteredMutableViewFunction(m, to);
}
/*!
\fn const char *QMetaType::typeName(int typeId)
\deprecated

View File

@ -1750,11 +1750,19 @@ QT_FOR_EACH_STATIC_TYPE(Q_DECLARE_BUILTIN_METATYPE)
QT_BEGIN_NAMESPACE
namespace QtPrivate {
// out-of-line helpers to reduce template code bloat ("SCARY") and improve compile times:
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToPairVariantInterface(QMetaType m);
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType m);
Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType m);
Q_CORE_EXPORT bool hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType m);
Q_CORE_EXPORT bool hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType m);
}
template <typename T>
inline bool QtPrivate::IsMetaTypePair<T, true>::registerConverter()
{
const QMetaType to = QMetaType::fromType<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
if (!QtPrivate::hasRegisteredConverterFunctionToPairVariantInterface(QMetaType::fromType<T>())) {
QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor<T> o;
return QMetaType::registerConverter<T, QtMetaTypePrivate::QPairVariantInterfaceImpl>(o);
}
@ -1786,8 +1794,7 @@ struct SequentialValueTypeIsMetaType<T, true>
{
static bool registerConverter()
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaSequence>>(o);
}
@ -1796,8 +1803,7 @@ struct SequentialValueTypeIsMetaType<T, true>
static bool registerMutableView()
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaSequence>>();
if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaSequence(QMetaType::fromType<T>())) {
QSequentialIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaSequence>>(o);
}
@ -1830,8 +1836,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
{
static bool registerConverter()
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
if (!QMetaType::hasRegisteredConverterFunction(QMetaType::fromType<T>(), to)) {
if (!QtPrivate::hasRegisteredConverterFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableConvertFunctor<T> o;
return QMetaType::registerConverter<T, QIterable<QMetaAssociation>>(o);
}
@ -1840,8 +1845,7 @@ struct AssociativeKeyTypeIsMetaType<T, true> : AssociativeMappedTypeIsMetaType<T
static bool registerMutableView()
{
const QMetaType to = QMetaType::fromType<QIterable<QMetaAssociation>>();
if (!QMetaType::hasRegisteredMutableViewFunction(QMetaType::fromType<T>(), to)) {
if (!QtPrivate::hasRegisteredMutableViewFunctionToIterableMetaAssociation(QMetaType::fromType<T>())) {
QAssociativeIterableMutableViewFunctor<T> o;
return QMetaType::registerMutableView<T, QIterable<QMetaAssociation>>(o);
}