From 790268130926f318c007b41439c9d60463666e34 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 31 Mar 2014 09:58:13 +0200 Subject: Fix performance regression of parent setting during QML object creation This showed up in the profiles again: In QML we create a lot of objects with many children and sending a child event each time is expensive. That's why the VME didn't do that and hadn't done so in ages. This patch restores that behavior and aspect of loading performance. Change-Id: I5078fe330d913dc832b284aaecf031152dc80802 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlobjectcreator.cpp | 3 +-- tests/auto/qml/qqmllanguage/testtypes.cpp | 17 +++++++++++++++++ tests/auto/qml/qqmllanguage/testtypes.h | 8 +++++++- tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 12 ++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index e4e0d63b37..9d1f5758a8 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1073,9 +1073,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo return 0; } } - // ### use no-event variant if (parent) - instance->setParent(parent); + QQml_setParent_noEvent(instance, parent); ddata = QQmlData::get(instance, /*create*/true); ddata->lineNumber = obj->location.line; diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 8dd788869b..226206edfd 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -205,3 +205,20 @@ void SimpleObjectCustomParser::setCustomData(QObject *object, const QByteArray & o->setCustomBindingsCount(data.toInt(&ok)); Q_ASSERT(ok); } + + +MyQmlObject::MyQmlObject() + : m_value(-1) + , m_interface(0) + , m_qmlobject(0) + , m_childAddedEventCount(0) +{ + qRegisterMetaType("MyCustomVariantType"); +} + +bool MyQmlObject::event(QEvent *event) +{ + if (event->type() == QEvent::ChildAdded) + m_childAddedEventCount++; + return QObject::event(event); +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 1a4cca2e8d..1f34309a5e 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -119,7 +119,7 @@ class MyQmlObject : public QObject, public MyInterface Q_INTERFACES(MyInterface) public: - MyQmlObject() : m_value(-1), m_interface(0), m_qmlobject(0) { qRegisterMetaType("MyCustomVariantType"); } + MyQmlObject(); int value() const { return m_value; } void setValue(int v) { m_value = v; } @@ -161,6 +161,8 @@ public: QJSValue qjsvalue() const { return m_qjsvalue; } void setQJSValue(const QJSValue &value) { m_qjsvalue = value; emit qjsvalueChanged(); } + int childAddedEventCount() const { return m_childAddedEventCount; } + public slots: void basicSlot() { qWarning("MyQmlObject::basicSlot"); } void basicSlotWithArgs(int v) { qWarning("MyQmlObject::basicSlotWithArgs(%d)", v); } @@ -173,6 +175,9 @@ signals: void signalWithDefaultArg(int parameter = 5); void qjsvalueChanged(); +protected: + virtual bool event(QEvent *event); + private: friend class tst_qqmllanguage; int m_value; @@ -181,6 +186,7 @@ private: MyCustomVariantType m_custom; int m_propertyWithNotify; QJSValue m_qjsvalue; + int m_childAddedEventCount; }; QML_DECLARE_TYPE(MyQmlObject) QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 619c7719f6..ede499b336 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -236,6 +236,8 @@ private slots: void rootObjectInCreationNotForSubObjects(); + void noChildEvents(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -3677,6 +3679,16 @@ void tst_qqmllanguage::rootObjectInCreationNotForSubObjects() QVERIFY(!ddata->rootObjectInCreation); } +void tst_qqmllanguage::noChildEvents() +{ + QQmlComponent component(&engine); + component.setData("import QtQml 2.0; import Test 1.0; MyQmlObject { property QtObject child: QtObject {} }", QUrl()); + VERIFY_ERRORS(0); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->childAddedEventCount(), 0); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" -- cgit v1.2.3