aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4qobjectwrapper_p.h
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@crimson.no>2017-03-02 09:41:16 +0100
committerRobin Burchell <robin.burchell@crimson.no>2017-04-25 15:34:14 +0000
commit1a3dd2031a8151bf9d50d070840fb664f7fd5d44 (patch)
treed0b0c909e31d8128e63384fbb439037b2d62522f /src/qml/jsruntime/qv4qobjectwrapper_p.h
parenta7cb3ffb34dce269e0d1073bdd3ebfc39ade44a2 (diff)
QObjectWrapper: Try harder to avoid creating wrappers if we can
When searching a QObject for properties, try to find QObject properties first, and then bail if we don't find a match and the object is not already wrapped. It makes no sense to wrap the object just to check the (empty) JS side props, which is often the case with QmlContextWrapper's scopeObject and contextObject. This can especially be seen when looking at QML's model activity, as they set a context object in order to hijack lookup of model data & index. This can be seen in a test like the following: Repeater { model: 10 delegate: Text { text: index } } Before this patch, the 'index' access would previously trigger wrapping of the QQmlDelegateModelItem. The same applies to the 'model' prop etc. Noteworthy improvements of a full qmlbench run that aren't part of the "usual" statistical noise are generally around the 5% mark. Outside performance, the advantages are also clear on memory. Examining for instance delegates_flipable.qml with QV4_MM_STATS=1 on my MBP: Before: Freed JS type: QmlContext (5000 instances) Freed JS type: QObjectWrapper (5000 instances) Freed JS type: QmlContextWrapper (5000 instances) Freed JS type: QQuickItemWrapper (5000 instances) After: Freed JS type: QmlContext (5000 instances) Freed JS type: QmlContextWrapper (5000 instances) Freed JS type: QQuickItemWrapper (5000 instances) ... which is what we expect, no more QObjectWrappers here, a lot less garbage to clear up. Timewise, while the measured mark/sweep times are not stable, there is a proportional decrease of about 40% in time for both mark and sweep phases in the GC (slightly more on TX1 than desktop, curiously). Finally, GC's memory use is quite stable for each round of the test, and in this case, we see a decrease of 378kb used at the time of each GC. Before: Allocated 2515968 bytes in 39 chunks Used memory before GC: 2489824 Used memory after GC : 889856 Freed up bytes : 1599968 After: Allocated 2128896 bytes in 33 chunks Used memory before GC: 2098304 Used memory after GC : 818304 Freed up bytes : 1280000 As a final note, while this provides an improvement to many of qmlbench's benchmarks, as they make heavy use of Repeater, these benefits should map quite well to real world applications as well: anything that uses item views will likely see a significant reduction to the amount of GC'd objects. In the future, it would be nice to have tests for the amount of garbage created by various activities, but that is an item for another day. Change-Id: Idd14180e689235eea8883d68487570b0e14d47e6 Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4qobjectwrapper_p.h')
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 55700d17c1..018e444f7c 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -189,6 +189,7 @@ protected:
static ReturnedValue create(ExecutionEngine *engine, QObject *object);
+ static QQmlPropertyData *findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local);
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);