Inline access to the QBindingStorage
And inline the fast checks inside the methods in QBindingStorage. This allows QObjectBindableProperty and friends to inline all the fast checks and almost completely eliminates the overhead for property accesses when no bindings are being used. Read and write times of QObject based properties when no bindings are being used: Read Write Old style property: 3.8ns 7.3ns QObjectBindableProperty (no notification): 4.5ns 4.3ns QObjectBindableProperty (with signal): 4.5ns 7.6ns QObjectBindableProperty (inline accessors): 3.2ns 3.4ns Numbers without this patch: Old style property: 3.8ns 7.9ns QObjectBindableProperty (no notification): 7.2ns 7.7ns QObjectBindableProperty (with signal): 7.2ns 16.0ns QObjectBindableProperty (inline accessors): 6.3ns 6.7ns Change-Id: Ifd1fa3a489c3be8b1468c0b88af547aac397f412 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 98c82fb445acf45cc4c4bc86a5adda43358127bf) Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
92d60ae589
commit
de4a73ebd6
@ -4057,24 +4057,6 @@ QList<QByteArray> QObject::dynamicPropertyNames() const
|
||||
return QList<QByteArray>();
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QBindingStorage *QObject::bindingStorage()
|
||||
{
|
||||
Q_D(QObject);
|
||||
return &d->bindingStorage;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
const QBindingStorage *QObject::bindingStorage() const
|
||||
{
|
||||
Q_D(const QObject);
|
||||
return &d->bindingStorage;
|
||||
}
|
||||
|
||||
#endif // QT_NO_PROPERTIES
|
||||
|
||||
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <QtCore/qmetatype.h>
|
||||
|
||||
#include <QtCore/qobject_impl.h>
|
||||
#include <QtCore/qproperty.h>
|
||||
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
@ -107,6 +108,7 @@ public:
|
||||
uint unused : 24;
|
||||
int postedEvents;
|
||||
QDynamicMetaObjectData *metaObject;
|
||||
QBindingStorage bindingStorage;
|
||||
QMetaObject *dynamicMetaObject() const;
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
@ -372,8 +374,8 @@ public:
|
||||
bool setProperty(const char *name, const QVariant &value);
|
||||
QVariant property(const char *name) const;
|
||||
QList<QByteArray> dynamicPropertyNames() const;
|
||||
QBindingStorage *bindingStorage();
|
||||
const QBindingStorage *bindingStorage() const;
|
||||
QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; }
|
||||
const QBindingStorage *bindingStorage() const { return &d_ptr->bindingStorage; }
|
||||
#endif // QT_NO_PROPERTIES
|
||||
|
||||
Q_SIGNALS:
|
||||
|
@ -384,7 +384,6 @@ public:
|
||||
// these objects are all used to indicate that a QObject was deleted
|
||||
// plus QPointer, which keeps a separate list
|
||||
QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount;
|
||||
QBindingStorage bindingStorage;
|
||||
};
|
||||
|
||||
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_RELOCATABLE_TYPE);
|
||||
|
@ -1426,8 +1426,7 @@ struct QBindingStoragePrivate
|
||||
|
||||
QPropertyBindingData *get(const QUntypedPropertyData *data)
|
||||
{
|
||||
if (!d)
|
||||
return nullptr;
|
||||
Q_ASSERT(d);
|
||||
Q_ASSERT(d->size && (d->size & (d->size - 1)) == 0); // size is a power of two
|
||||
size_t index = qHash(data) & (d->size - 1);
|
||||
Pair *p = pairs(d);
|
||||
@ -1497,13 +1496,13 @@ QBindingStorage::~QBindingStorage()
|
||||
QBindingStoragePrivate(d).destroy();
|
||||
}
|
||||
|
||||
void QBindingStorage::maybeUpdateBindingAndRegister(const QUntypedPropertyData *data) const
|
||||
void QBindingStorage::maybeUpdateBindingAndRegister_helper(const QUntypedPropertyData *data) const
|
||||
{
|
||||
Q_ASSERT(bindingStatus);
|
||||
QUntypedPropertyData *dd = const_cast<QUntypedPropertyData *>(data);
|
||||
auto storage = bindingStatus->currentlyEvaluatingBinding ?
|
||||
QBindingStoragePrivate(d).getAndCreate(dd) :
|
||||
QBindingStoragePrivate(d).get(dd);
|
||||
(d ? QBindingStoragePrivate(d).get(dd) : nullptr);
|
||||
if (!storage)
|
||||
return;
|
||||
if (auto *binding = storage->binding())
|
||||
@ -1511,12 +1510,12 @@ void QBindingStorage::maybeUpdateBindingAndRegister(const QUntypedPropertyData *
|
||||
storage->registerWithCurrentlyEvaluatingBinding();
|
||||
}
|
||||
|
||||
QPropertyBindingData *QBindingStorage::bindingData(const QUntypedPropertyData *data) const
|
||||
QPropertyBindingData *QBindingStorage::bindingData_helper(const QUntypedPropertyData *data) const
|
||||
{
|
||||
return QBindingStoragePrivate(d).get(data);
|
||||
}
|
||||
|
||||
QPropertyBindingData *QBindingStorage::bindingData(QUntypedPropertyData *data, bool create)
|
||||
QPropertyBindingData *QBindingStorage::bindingData_helper(QUntypedPropertyData *data, bool create)
|
||||
{
|
||||
auto storage = create ?
|
||||
QBindingStoragePrivate(d).getAndCreate(data) :
|
||||
|
@ -41,8 +41,8 @@
|
||||
#define QPROPERTY_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
@ -774,7 +774,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct QBindingStatus;
|
||||
namespace QtPrivate {
|
||||
|
||||
struct BindingEvaluationState;
|
||||
struct CurrentCompatProperty;
|
||||
}
|
||||
|
||||
struct QBindingStatus
|
||||
{
|
||||
QtPrivate::BindingEvaluationState *currentlyEvaluatingBinding = nullptr;
|
||||
QtPrivate::CurrentCompatProperty *currentCompatProperty = nullptr;
|
||||
};
|
||||
|
||||
struct QBindingStorageData;
|
||||
class Q_CORE_EXPORT QBindingStorage
|
||||
@ -790,9 +800,28 @@ public:
|
||||
|
||||
bool isEmpty() { return !d; }
|
||||
|
||||
void maybeUpdateBindingAndRegister(const QUntypedPropertyData *data) const;
|
||||
QtPrivate::QPropertyBindingData *bindingData(const QUntypedPropertyData *data) const;
|
||||
QtPrivate::QPropertyBindingData *bindingData(QUntypedPropertyData *data, bool create);
|
||||
void maybeUpdateBindingAndRegister(const QUntypedPropertyData *data) const
|
||||
{
|
||||
if (!d && !bindingStatus->currentlyEvaluatingBinding)
|
||||
return;
|
||||
maybeUpdateBindingAndRegister_helper(data);
|
||||
}
|
||||
QtPrivate::QPropertyBindingData *bindingData(const QUntypedPropertyData *data) const
|
||||
{
|
||||
if (!d)
|
||||
return nullptr;
|
||||
return bindingData_helper(data);
|
||||
}
|
||||
QtPrivate::QPropertyBindingData *bindingData(QUntypedPropertyData *data, bool create)
|
||||
{
|
||||
if (!d && !create)
|
||||
return nullptr;
|
||||
return bindingData_helper(data, create);
|
||||
}
|
||||
private:
|
||||
void maybeUpdateBindingAndRegister_helper(const QUntypedPropertyData *data) const;
|
||||
QtPrivate::QPropertyBindingData *bindingData_helper(const QUntypedPropertyData *data) const;
|
||||
QtPrivate::QPropertyBindingData *bindingData_helper(QUntypedPropertyData *data, bool create);
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,12 +148,6 @@ struct CurrentCompatProperty
|
||||
|
||||
}
|
||||
|
||||
struct QBindingStatus
|
||||
{
|
||||
QtPrivate::BindingEvaluationState *currentlyEvaluatingBinding = nullptr;
|
||||
QtPrivate::CurrentCompatProperty *currentCompatProperty = nullptr;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QPropertyBindingPrivate : public QtPrivate::RefCounted
|
||||
{
|
||||
private:
|
||||
|
@ -52,7 +52,6 @@
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QExplicitlySharedDataPointer>
|
||||
#include <QtCore/qtaggedpointer.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
|
||||
|
@ -97,14 +97,14 @@ void tst_toolsupport::offsets_data()
|
||||
{
|
||||
QTestData &data = QTest::newRow("sizeof(QObjectData)")
|
||||
<< sizeof(QObjectData);
|
||||
data << 36 << 64; // vptr + 2 ptr + (2*ptr + int) + 2 int + ptr
|
||||
data << 44 << 80; // vptr + 2 ptr + (2*ptr + int) + 2 int + ptr
|
||||
}
|
||||
|
||||
#if RUN_MEMBER_OFFSET_TEST
|
||||
{
|
||||
QTestData &data = QTest::newRow("QObjectPrivate::extraData")
|
||||
<< pmm_to_offsetof(&QObjectPrivate::extraData);
|
||||
data << 36 << 64; // sizeof(QObjectData)
|
||||
data << 44 << 80; // sizeof(QObjectData)
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user