diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-11-24 11:08:13 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-11-26 21:40:02 +0100 |
commit | 98c82fb445acf45cc4c4bc86a5adda43358127bf (patch) | |
tree | 7831d854f24cbd9eef4bbcf10af7e120fb332349 | |
parent | 5283ee71040dc2f3a762e9cc5e807fb17587e9b7 (diff) |
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
Pick-to: dev 6.0.0
Change-Id: Ifd1fa3a489c3be8b1468c0b88af547aac397f412
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 18 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.h | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 11 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty.h | 41 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty_p.h | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qpropertyprivate.h | 1 | ||||
-rw-r--r-- | tests/auto/other/toolsupport/tst_toolsupport.cpp | 4 |
8 files changed, 46 insertions, 42 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 54bed0564f..9c87c57a10 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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 diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index ca72373073..5742db1c22 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -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: diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 5fc12c3165..43b0a53335 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -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_MOVABLE_TYPE); diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 147103aed9..3eab02ac86 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -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) : diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index d612486e2c..858724c0b7 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -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); }; diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h index 9a0daaee3a..8f6577a2de 100644 --- a/src/corelib/kernel/qproperty_p.h +++ b/src/corelib/kernel/qproperty_p.h @@ -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: diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h index 6bac03243b..0edfe5781b 100644 --- a/src/corelib/kernel/qpropertyprivate.h +++ b/src/corelib/kernel/qpropertyprivate.h @@ -52,7 +52,6 @@ // #include <QtCore/qglobal.h> -#include <QtCore/QExplicitlySharedDataPointer> #include <QtCore/qtaggedpointer.h> #include <QtCore/qmetatype.h> diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp index 7acf1ad08d..bd6cc8b293 100644 --- a/tests/auto/other/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp @@ -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) } { |